bud 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bud/rewrite.rb CHANGED
@@ -8,11 +8,11 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
8
8
  @bud_instance = bud_instance
9
9
  @ops = {:<< => 1, :< => 1, :<= => 1}
10
10
  @monotonic_whitelist = {
11
- :== => 1, :+ => 1, :<= => 1, :- => 1, :< => 1, :> => 1,
12
- :* => 1, :pairs => 1, :matches => 1, :combos => 1, :flatten => 1,
13
- :lefts => 1, :rights => 1, :map => 1, :flat_map => 1, :pro => 1,
14
- :schema => 1, :keys => 1, :values => 1, :payloads => 1, :~ => 1
15
- }
11
+ :== => 1, :+ => 1, :<= => 1, :- => 1, :< => 1, :> => 1,
12
+ :* => 1, :pairs => 1, :matches => 1, :combos => 1, :flatten => 1,
13
+ :lefts => 1, :rights => 1, :map => 1, :flat_map => 1, :pro => 1,
14
+ :schema => 1, :keys => 1, :values => 1, :payloads => 1, :~ => 1
15
+ }
16
16
  @temp_ops = {:-@ => 1, :~ => 1, :+@ => 1}
17
17
  @tables = {}
18
18
  @nm = false
@@ -115,7 +115,9 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
115
115
  drain(exp)
116
116
  end
117
117
 
118
- # Look for top-level map on a base-table on rhs, and rewrite to pro
118
+ # We want to rewrite "map" calls on BudCollections to "pro" calls. It is hard
119
+ # to do this accurately (issue #225), so we just replace map calls liberally
120
+ # and define Enumerable#pro as an alias for "map".
119
121
  def map2pro(exp)
120
122
  if exp[1] and exp[1][0] and exp[1][0] == :iter \
121
123
  and exp[1][1] and exp[1][1][1] and exp[1][1][1][0] == :call
@@ -152,10 +154,11 @@ class AttrNameRewriter < SexpProcessor # :nodoc: all
152
154
  if exp[2] and exp[2][0] == :lasgn and @collnames.size == 1 #single-table iter
153
155
  raise Bud::CompileError, "nested redefinition of block variable \"#{exp[2][1]}\" not allowed" if @iterhash[exp[2][1]]
154
156
  @iterhash[exp[2][1]] = @collnames[0]
155
- elsif exp[2] and exp[2][0] == :lasgn and @collnames.size > 1 # join iter with lefts/rights
156
- if exp[1] and exp[1][2] == :lefts
157
+ elsif exp[2] and exp[2][0] == :lasgn and @collnames.size > 1 and exp[1] # join iter with lefts/rights
158
+ case exp[1][2]
159
+ when :lefts
157
160
  @iterhash[exp[2][1]] = @collnames[0]
158
- elsif exp[1] and exp[1][2] == :rights
161
+ when :rights
159
162
  @iterhash[exp[2][1]] = @collnames[1]
160
163
  else
161
164
  raise Bud::CompileError, "nested redefinition of block variable \"#{exp[2][1]}\" not allowed" if @iterhash[exp[2][1]]
@@ -315,6 +318,7 @@ class TempExpander < SexpProcessor # :nodoc: all
315
318
  super()
316
319
  self.require_empty = false
317
320
  self.expected = Sexp
321
+ @keyword = :temp
318
322
 
319
323
  @tmp_tables = []
320
324
  @did_work = false
@@ -322,7 +326,6 @@ class TempExpander < SexpProcessor # :nodoc: all
322
326
 
323
327
  def process_defn(exp)
324
328
  tag, name, args, scope = exp
325
-
326
329
  if name.to_s =~ /^__bloom__.+/
327
330
  block = scope[1]
328
331
 
@@ -337,35 +340,41 @@ class TempExpander < SexpProcessor # :nodoc: all
337
340
  # correct the misparsing.
338
341
  if n.sexp_type == :iter
339
342
  iter_body = n.sexp_body
340
-
341
- if iter_body.first.sexp_type == :call
342
- call_node = iter_body.first
343
-
344
- _, recv, meth, meth_args = call_node
345
- if meth == :temp and recv.nil?
346
- _, lhs, op, rhs = meth_args.sexp_body.first
347
-
348
- old_rhs_body = rhs.sexp_body
349
- rhs[1] = s(:iter)
350
- rhs[1] += old_rhs_body
351
- rhs[1] += iter_body[1..-1]
352
- block[i] = n = call_node
353
- @did_work = true
354
- end
343
+ new_n = fix_temp_decl(iter_body)
344
+ unless new_n.nil?
345
+ block[i] = n = new_n
346
+ @did_work = true
355
347
  end
356
348
  end
357
349
 
358
350
  _, recv, meth, meth_args = n
359
- if meth == :temp and recv.nil?
360
- block[i] = rewrite_temp(n)
351
+ if meth == @keyword and recv.nil?
352
+ block[i] = rewrite_me(n)
361
353
  @did_work = true
362
354
  end
363
355
  end
364
356
  end
365
-
366
357
  s(tag, name, args, scope)
367
358
  end
368
359
 
360
+ def fix_temp_decl(iter_body)
361
+ if iter_body.first.sexp_type == :call
362
+ call_node = iter_body.first
363
+
364
+ _, recv, meth, meth_args = call_node
365
+ if meth == @keyword and recv.nil?
366
+ _, lhs, op, rhs = meth_args.sexp_body.first
367
+
368
+ old_rhs_body = rhs.sexp_body
369
+ rhs[1] = s(:iter)
370
+ rhs[1] += old_rhs_body
371
+ rhs[1] += iter_body[1..-1]
372
+ return call_node
373
+ end
374
+ end
375
+ return nil
376
+ end
377
+
369
378
  def get_state_meth(klass)
370
379
  return if @tmp_tables.empty?
371
380
  block = s(:block)
@@ -375,12 +384,12 @@ class TempExpander < SexpProcessor # :nodoc: all
375
384
  block << s(:call, nil, :temp, args)
376
385
  end
377
386
 
378
- meth_name = Module.make_state_meth_name(klass).to_s + "__tmp"
387
+ meth_name = Module.make_state_meth_name(klass).to_s + "__" + @keyword.to_s
379
388
  return s(:defn, meth_name.to_sym, s(:args), s(:scope, block))
380
389
  end
381
390
 
382
391
  private
383
- def rewrite_temp(exp)
392
+ def rewrite_me(exp)
384
393
  _, recv, meth, args = exp
385
394
 
386
395
  raise Bud::CompileError unless recv == nil
@@ -397,6 +406,107 @@ class TempExpander < SexpProcessor # :nodoc: all
397
406
  end
398
407
  end
399
408
 
409
+ # We do four things here for each "with" block
410
+ # 1) Remove it from the AST
411
+ # 2) Use rewrite_me in the parent class to get the collection name pushed onto @tmp_tables.
412
+ # 3) Extract the definition of the "with" collection and push it onto @with_defns
413
+ # 4) Extract the rules in the body of the "with" block and push it onto @with_rules
414
+
415
+ class WithExpander < TempExpander
416
+ attr_reader :with_rules, :with_defns
417
+ def initialize
418
+ super()
419
+ @keyword = :with
420
+ @with_rules = []
421
+ @with_defns = []
422
+ end
423
+
424
+ def process_defn(exp)
425
+ tag, name, args, scope = exp
426
+ if name.to_s =~ /^__bloom__.+/
427
+ block = scope[1]
428
+
429
+ block.each_with_index do |n,i|
430
+ if i == 0
431
+ raise Bud::CompileError if n != :block
432
+ next
433
+ end
434
+
435
+ # temp declarations are misparsed if the RHS contains certain constructs
436
+ # (e.g., group, "do |f| ... end" rather than "{|f| ... }"). Rewrite to
437
+ # correct the misparsing.
438
+ if n.sexp_type == :iter
439
+ block[i] = nil
440
+ iter_body = n.sexp_body
441
+ n = fix_temp_decl(iter_body)
442
+ @with_defns.push n
443
+ @did_work = true unless n.nil?
444
+ end
445
+
446
+ _, recv, meth, meth_args = n
447
+ if meth == @keyword and recv.nil?
448
+ block[i] = nil
449
+ n = rewrite_me(n)
450
+ @with_defns.push n
451
+ @did_work = true unless n.nil?
452
+ end
453
+ end
454
+ end
455
+ block.compact! unless block.nil? # remove the nils that got pulled out
456
+
457
+ return s(tag, name, args, scope)
458
+ end
459
+
460
+ def get_state_meth(klass)
461
+ return if @tmp_tables.empty?
462
+ block = s(:block)
463
+
464
+ t = @tmp_tables.pop
465
+ args = s(:arglist, s(:lit, t.to_sym))
466
+ block << s(:call, nil, :temp, args)
467
+
468
+ meth_name = Module.make_state_meth_name(klass).to_s + "__" + @keyword.to_s
469
+ return s(:defn, meth_name.to_sym, s(:args), s(:scope, block))
470
+ end
471
+
472
+ private
473
+ def rewrite_me(exp)
474
+ _, recv, meth, args = exp
475
+
476
+ raise Bud::CompileError unless recv == nil
477
+ nest_call = args.sexp_body.first
478
+ raise Bud::CompileError unless nest_call.sexp_type == :call
479
+
480
+ nest_recv, nest_op, nest_args = nest_call.sexp_body
481
+ raise Bud::CompileError unless nest_recv.sexp_type == :lit
482
+
483
+ tmp_name = nest_recv.sexp_body.first
484
+ @tmp_tables.push tmp_name
485
+ nest_block = args.sexp_body[1]
486
+ if nest_block.first == :call
487
+ # a one-rule block doesn't get wrapped in a block. wrap it ourselves.
488
+ nest_block = s(:block, nest_block)
489
+ end
490
+ @with_rules.push nest_block
491
+ new_recv = s(:call, nil, tmp_name, s(:arglist))
492
+ return s(:call, new_recv, nest_op, nest_args)
493
+ end
494
+
495
+ undef get_state_meth
496
+
497
+ public
498
+ def get_state_meth(klass)
499
+ return if @tmp_tables.empty?
500
+ block = s(:block)
501
+
502
+ args = s(:arglist, s(:lit, @tmp_tables.pop.to_sym))
503
+ block << s(:call, nil, :temp, args)
504
+
505
+ meth_name = Module.make_state_meth_name(klass).to_s + "__" + @keyword.to_s
506
+ return s(:defn, meth_name.to_sym, s(:args), s(:scope, block))
507
+ end
508
+ end
509
+
400
510
  class DefnRenamer < SexpProcessor # :nodoc: all
401
511
  def initialize(local_name, rename_tbl)
402
512
  super()
@@ -448,10 +558,24 @@ module ModuleRewriter # :nodoc: all
448
558
  # the import site. Note that additional rewrites are needed to ensure that
449
559
  # code in the import site that accesses module contents does the right thing;
450
560
  # see Bud#rewrite_local_methods.
561
+
562
+ @@with_id = 0 # upon initialize
563
+ def self.with_id
564
+ @@with_id
565
+ end
566
+
567
+ def self.incr_with_id
568
+ @@with_id += 1
569
+ end
570
+
451
571
  def self.do_import(import_site, mod, local_name)
452
- ast = get_module_ast(mod)
572
+ # ast_process_withs modifies its argument as a side-effect
573
+ # and returns a matching ast.
574
+ # hence we run it before the other rewrites.
575
+ ast = ast_process_withs(mod)
453
576
  ast = ast_flatten_nested_refs(ast, mod.bud_import_table)
454
577
  ast = ast_process_temps(ast, mod)
578
+
455
579
  ast, new_mod_name = ast_rename_module(ast, import_site, mod, local_name)
456
580
  rename_tbl = {}
457
581
  ast = ast_rename_methods(ast, local_name, rename_tbl)
@@ -461,7 +585,6 @@ module ModuleRewriter # :nodoc: all
461
585
  str = Ruby2Ruby.new.process(ast)
462
586
  rv = import_site.module_eval str
463
587
  raise Bud::BudError unless rv.nil?
464
-
465
588
  return new_mod_name
466
589
  end
467
590
 
@@ -486,15 +609,16 @@ module ModuleRewriter # :nodoc: all
486
609
  def self.get_raw_parse_tree(klass)
487
610
  pt = RawParseTree.new(false)
488
611
  klassname = klass.name
612
+ klassname = klass.to_s if klassname.empty? #("anon_" + Process.pid.to_s + "_" + klass.object_id.to_s) if klassname.empty
489
613
  klassname = klassname.to_sym
490
614
 
491
615
  code = if Class === klass then
492
- sc = klass.superclass
493
- sc_name = ((sc.nil? or sc.name.empty?) ? "nil" : sc.name).intern
494
- [:class, klassname, [:const, sc_name]]
495
- else
496
- [:module, klassname]
497
- end
616
+ sc = klass.superclass
617
+ sc_name = ((sc.nil? or sc.name.empty?) ? "nil" : sc.name).intern
618
+ [:class, klassname, [:const, sc_name]]
619
+ else
620
+ [:module, klassname]
621
+ end
498
622
 
499
623
  method_names = klass.private_instance_methods false
500
624
  # protected methods are included in instance_methods, go figure!
@@ -542,9 +666,63 @@ module ModuleRewriter # :nodoc: all
542
666
  # Insert the new extra state method into the module's AST
543
667
  ast << new_meth
544
668
  end
545
-
546
669
  return ast
547
670
  end
671
+
672
+ def self.ast_mangle_with(w,klass)
673
+ r2r = Ruby2Ruby.new
674
+
675
+ while st = w.get_state_meth(klass)
676
+ # generate the module
677
+ tmpmod = Module.new
678
+
679
+ # add a state block to define a temp for the collection name
680
+ state_src = r2r.process(st)
681
+ tmpmod.module_eval(state_src)
682
+
683
+ # add a bloom block
684
+ bloom_blk = s(:defn, :__bloom__rules, s(:args), s(:scope, s(:block)))
685
+ inblk = bloom_blk[3][1]
686
+
687
+ # add in the rule that was in the "with" definition
688
+ newdefn = w.with_defns.pop
689
+ inblk << newdefn unless newdefn.nil?
690
+
691
+ # add in all the rules from the body of the "with" block
692
+ newrules = w.with_rules.pop
693
+ newrules.each_with_index do |ast, i|
694
+ inblk << ast unless i == 0
695
+ end
696
+ bloom_src = r2r.process(bloom_blk)
697
+
698
+ # eval all that Ruby we generated and import new Module into our code
699
+ tmpmod.module_eval(bloom_src)
700
+ modname = "with__"+ModuleRewriter.with_id.to_s
701
+ klass.import tmpmod => modname.to_sym
702
+
703
+ ModuleRewriter.incr_with_id
704
+ end
705
+ end
706
+
707
+ def self.ast_process_withs(mod)
708
+ # strategy to handle withs:
709
+ # 1) run WithExpander#process to delete the "with" blocks and extract their contents
710
+ # 2) get the state and rules mangled appropriately into modules
711
+ # 3) run mod.import on each
712
+ # 4) call self.get_raw_parse_tree on the result to generate an AST
713
+
714
+ ast = get_module_ast(mod)
715
+ w = WithExpander.new
716
+ ast = w.process(ast)
717
+ mod_s, name_s, blocks = ast[0], ast[1], ast[2..-1]
718
+ tag, name, args, scope = blocks[0]
719
+
720
+ self.ast_mangle_with(w,mod)
721
+
722
+ retval = Unifier.new.process(self.get_raw_parse_tree(mod))
723
+ return retval
724
+ # return s(mod_s, name_s, *blocks)
725
+ end
548
726
 
549
727
  # Rename the given module's name to be a mangle of import site, imported
550
728
  # module, and local bind name. We also rename all the instance methods defined
data/lib/bud/server.rb CHANGED
@@ -17,28 +17,31 @@ module Bud
17
17
  message_received(obj)
18
18
  end
19
19
 
20
+ begin
21
+ @bud.tick_internal if @bud.running_async
22
+ rescue Exception
23
+ # If we raise an exception here, EM dies, which causes problems (e.g.,
24
+ # other Bud instances in the same process will crash). Ignoring the
25
+ # error isn't best though -- we should do better (#74).
26
+ puts "Exception handling network messages: #{$!}"
27
+ puts "Inbound messages:"
28
+ @bud.inbound.each do |m|
29
+ puts " #{m[1].inspect} (channel: #{m[0]})"
30
+ end
31
+ @bud.inbound.clear
32
+ end
33
+
20
34
  @bud.rtracer.sleep if @bud.options[:rtrace]
21
35
  end
22
36
 
23
37
  def message_received(obj)
24
- # puts "#{@bud.ip_port} <= #{obj.inspect}"
25
- unless (obj.class <= Array and obj.length == 2 and not
26
- @bud.tables[obj[0].to_sym].nil? and obj[1].class <= Array)
38
+ unless (obj.class <= Array and obj.length == 2 and
39
+ @bud.tables.include?(obj[0].to_sym) and obj[1].class <= Array)
27
40
  raise BudError, "Bad inbound message of class #{obj.class}: #{obj.inspect}"
28
41
  end
29
42
 
30
43
  @bud.rtracer.recv(obj) if @bud.options[:rtrace]
31
-
32
44
  @bud.inbound << obj
33
- begin
34
- @bud.tick unless @bud.lazy
35
- rescue Exception
36
- # If we raise an exception here, EM dies, which causes problems (e.g.,
37
- # other Bud instances in the same process will crash). Ignoring the
38
- # error isn't best though -- we should do better (#74).
39
- puts "Exception handling network message (channel '#{obj[0]}'): #{$!}"
40
- puts caller.join("\n")
41
- end
42
45
  end
43
46
  end
44
47
  end
data/lib/bud/state.rb CHANGED
@@ -21,7 +21,7 @@ module Bud
21
21
  end
22
22
  end
23
23
  end
24
-
24
+
25
25
  public
26
26
 
27
27
  def input # :nodoc: all
@@ -38,17 +38,52 @@ module Bud
38
38
  scratch(name, schema)
39
39
  end
40
40
 
41
- # declare a persistent collection. default schema <tt>[:key] => [:val]</tt>
41
+ # declare an in-memory, non-transient collection. default schema <tt>[:key] => [:val]</tt>.
42
42
  def table(name, schema=nil)
43
43
  define_collection(name)
44
44
  @tables[name] = Bud::BudTable.new(name, self, schema)
45
45
  end
46
+
47
+ # declare a syncronously-flushed persistent collection. default schema <tt>[:key] => [:val]</tt>.
48
+ def sync(name, storage, schema=nil)
49
+ define_collection(name)
50
+ case storage
51
+ when :dbm
52
+ @tables[name] = Bud::BudDbmTable.new(name, self, schema)
53
+ @dbm_tables[name] = @tables[name]
54
+ when :tokyo
55
+ @tables[name] = Bud::BudTcTable.new(name, self, schema)
56
+ @tc_tables[name] = @tables[name]
57
+ else
58
+ raise BudError, "Unknown synchronous storage engine #{storage.to_s}"
59
+ end
60
+ end
61
+
62
+ def store(name, storage, schema=nil)
63
+ define_collection(name)
64
+ case storage
65
+ when :zookeeper
66
+ # treat "schema" as a hash of options
67
+ options = schema
68
+ raise BudError, "Zookeeper tables require a :path option" if options[:path].nil?
69
+ options[:addr] ||= "localhost:2181"
70
+ @tables[name] = Bud::BudZkTable.new(name, options[:path], options[:addr], self)
71
+ @zk_tables[name] = @tables[name]
72
+ else
73
+ raise BudError, "Unknown async storage engine #{storage.to_s}"
74
+ end
75
+ end
46
76
 
47
77
  # declare a transient collection. default schema <tt>[:key] => [:val]</tt>
48
78
  def scratch(name, schema=nil)
49
79
  define_collection(name)
50
80
  @tables[name] = Bud::BudScratch.new(name, self, schema)
51
81
  end
82
+
83
+ def readonly(name, schema=nil)
84
+ define_collection(name)
85
+ @tables[name] = Bud::BudReadOnly.new(name, self, schema)
86
+ end
52
87
 
53
88
  # declare a scratch in a bloom statement lhs. schema inferred from rhs.
54
89
  def temp(name)
@@ -56,7 +91,7 @@ module Bud
56
91
  # defer schema definition until merge
57
92
  @tables[name] = Bud::BudTemp.new(name, self, nil, true)
58
93
  end
59
-
94
+
60
95
  # declare a transient network collection. default schema <tt>[:address, :val] => []</tt>
61
96
  def channel(name, schema=nil, loopback=false)
62
97
  define_collection(name)
@@ -84,7 +119,7 @@ module Bud
84
119
  def periodic(name, period=1)
85
120
  define_collection(name)
86
121
  raise BudError if @periodics.has_key? [name]
87
- @periodics << [name, gen_id, period]
122
+ @periodics << [name, period]
88
123
  @tables[name] = Bud::BudPeriodic.new(name, self)
89
124
  end
90
125
 
@@ -98,25 +133,4 @@ module Bud
98
133
  @tables[name] = Bud::BudTerminal.new(name, [:line], self)
99
134
  @channels[name] = @tables[name]
100
135
  end
101
-
102
- # declare a TokyoCabinet table
103
- def tctable(name, schema=nil)
104
- define_collection(name)
105
- @tables[name] = Bud::BudTcTable.new(name, self, schema)
106
- @tc_tables[name] = @tables[name]
107
- end
108
-
109
- # declare a dbm table
110
- def dbm_table(name, schema=nil)
111
- define_collection(name)
112
- @tables[name] = Bud::BudDbmTable.new(name, self, schema)
113
- @dbm_tables[name] = @tables[name]
114
- end
115
-
116
- # declare an Apache ZooKeeper table
117
- def zktable(name, path, addr="localhost:2181")
118
- define_collection(name)
119
- @tables[name] = Bud::BudZkTable.new(name, path, addr, self)
120
- @zk_tables[name] = @tables[name]
121
- end
122
136
  end
@@ -6,11 +6,14 @@ module Bud
6
6
  def initialize(name, bud_instance, given_schema)
7
7
  dbm_dir = bud_instance.options[:dbm_dir]
8
8
  raise BudError, "dbm support must be enabled via 'dbm_dir'" unless dbm_dir
9
+ if bud_instance.port.nil?
10
+ raise BudError, "use of dbm storage requires an explicit port to be specified in Bud initialization options"
11
+ end
12
+
9
13
  unless File.exists?(dbm_dir)
10
14
  Dir.mkdir(dbm_dir)
11
15
  puts "Created directory: #{dbm_dir}" unless bud_instance.options[:quiet]
12
16
  end
13
-
14
17
  dirname = "#{dbm_dir}/bud_#{bud_instance.port}"
15
18
  unless File.exists?(dirname)
16
19
  Dir.mkdir(dirname)
@@ -81,6 +84,7 @@ module Bud
81
84
  each_storage(&block)
82
85
  else
83
86
  b.each_value do |v|
87
+ tick_metrics if bud_instance.options[:metrics]
84
88
  yield v
85
89
  end
86
90
  end
@@ -91,6 +95,7 @@ module Bud
91
95
  @dbm.each do |k,v|
92
96
  k_ary = MessagePack.unpack(k)
93
97
  v_ary = MessagePack.unpack(v)
98
+ tick_metrics if bud_instance.options[:metrics]
94
99
  yield make_tuple(k_ary, v_ary)
95
100
  end
96
101
  end
@@ -10,6 +10,10 @@ module Bud
10
10
  def initialize(name, bud_instance, given_schema)
11
11
  tc_dir = bud_instance.options[:tc_dir]
12
12
  raise BudError, "TC support must be enabled via 'tc_dir'" unless tc_dir
13
+ if bud_instance.port.nil?
14
+ raise BudError, "use of dbm storage requires an explicit port to be specified in Bud initialization options"
15
+ end
16
+
13
17
  unless File.exists?(tc_dir)
14
18
  Dir.mkdir(tc_dir)
15
19
  puts "Created directory: #{tc_dir}" unless bud_instance.options[:quiet]
@@ -86,6 +90,7 @@ module Bud
86
90
  each_storage(&block)
87
91
  else
88
92
  b.each_value do |v|
93
+ tick_metrics if bud_instance.options[:metrics]
89
94
  yield v
90
95
  end
91
96
  end
@@ -96,6 +101,7 @@ module Bud
96
101
  @hdb.each do |k,v|
97
102
  k_ary = MessagePack.unpack(k)
98
103
  v_ary = MessagePack.unpack(v)
104
+ tick_metrics if bud_instance.options[:metrics]
99
105
  yield make_tuple(k_ary, v_ary)
100
106
  end
101
107
  end
@@ -9,7 +9,7 @@ module Bud
9
9
  class BudZkTable < BudCollection # :nodoc: all
10
10
  def initialize(name, zk_path, zk_addr, bud_instance)
11
11
  unless defined? HAVE_ZOOKEEPER
12
- raise BudError, "zookeeper gem is not installed: zktables cannot be used"
12
+ raise BudError, "zookeeper gem is not installed: zookeeper-backed stores cannot be used"
13
13
  end
14
14
 
15
15
  # schema = {[:key] => [:val]}
@@ -109,9 +109,9 @@ module Bud
109
109
  }
110
110
 
111
111
  # If we have new data, force a new Bud tick in the near future
112
- if need_tick and not @bud_instance.lazy
112
+ if need_tick and @bud_instance.running_async
113
113
  EventMachine::schedule {
114
- @bud_instance.tick
114
+ @bud_instance.tick_internal
115
115
  }
116
116
  end
117
117
  end
@@ -164,15 +164,15 @@ module Bud
164
164
  end
165
165
 
166
166
  superator "<+" do |o|
167
- raise BudError, "Illegal use of <+ with zktable '#{@tabname}' on left"
167
+ raise BudError, "Illegal use of <+ with zookeeper store '#{@tabname}' on left"
168
168
  end
169
169
 
170
170
  def <=(o)
171
- raise BudError, "Illegal use of <= with zktable '#{@tabname}' on left"
171
+ raise BudError, "Illegal use of <= with zookeeper store '#{@tabname}' on left"
172
172
  end
173
173
 
174
174
  def <<(o)
175
- raise BudError, "Illegal use of << with zktable '#{@tabname}' on left"
175
+ raise BudError, "Illegal use of << with zookeeper store '#{@tabname}' on left"
176
176
  end
177
177
  end
178
178
  end
data/lib/bud/viz.rb CHANGED
@@ -58,7 +58,11 @@ class VizOnline #:nodoc: all
58
58
  row = row[1]
59
59
  end
60
60
  newrow = [tab, @bud_instance.budtime, row]
61
- @logtab << newrow
61
+ begin
62
+ @logtab << newrow
63
+ rescue
64
+ raise "ERROR! #{@logtab} << #{newrow}"
65
+ end
62
66
 
63
67
  end
64
68
  end