bud 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bud/viz.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  require 'rubygems'
2
2
  require 'syntax/convertors/html'
3
3
  require 'gchart'
4
- require 'digest/md5'
5
4
  require 'bud/state'
6
5
 
7
6
  class VizOnline #:nodoc: all
8
7
  def initialize(bud_instance)
9
8
  @bud_instance = bud_instance
10
9
  return if bud_instance.class == Stratification or @bud_instance.class == DepAnalysis
11
- @meta_tables = {'t_rules' => 1, 't_depends' => 1, 't_table_info' => 1, 't_cycle' => 1, 't_stratum' => 1, 't_depends_tc' => 1, 't_table_schema' => 1}
10
+ @meta_tables = {'t_rules' => 1, 't_depends' => 1, 't_table_info' => 1, 't_cycle' => 1, 't_stratum' => 1, 't_depends_tc' => 1, 't_table_schema' => 1, 't_provides' => 1}
12
11
  @bud_instance.options[:dbm_dir] = "DBM_#{@bud_instance.class}_#{bud_instance.options[:tag]}_#{bud_instance.object_id}_#{bud_instance.port}"
13
12
  @table_info = bud_instance.tables[:t_table_info]
14
13
  @table_schema = bud_instance.tables[:t_table_schema]
@@ -57,13 +56,15 @@ class VizOnline #:nodoc: all
57
56
  if collection.class == Hash
58
57
  row = row[1]
59
58
  end
59
+ if collection.class == Bud::BudPeriodic
60
+ row = row[0]
61
+ end
60
62
  newrow = [tab, @bud_instance.budtime, row]
61
63
  begin
62
64
  @logtab << newrow
63
65
  rescue
64
- raise "ERROR! #{@logtab} << #{newrow}"
66
+ raise "ERROR! #{@logtab} << #{newrow.inspect} (etxt #{$!})"
65
67
  end
66
-
67
68
  end
68
69
  end
69
70
 
@@ -73,7 +74,8 @@ class VizOnline #:nodoc: all
73
74
  tab = t[0]
74
75
  next if tab == "the_big_log"
75
76
  next if @meta_tables[tab.to_s] and @bud_instance.budtime > 0
76
- add_rows(t[1], tab) unless t[1].class == Bud::BudPeriodic
77
+ # PAA: why did we previously exclude periodics?
78
+ add_rows(t[1], tab) #####unless t[1].class == Bud::BudPeriodic
77
79
  if t[1].class == Bud::BudChannel
78
80
  add_rows(t[1].pending, "#{tab}_snd")
79
81
  end
data/lib/bud/viz_util.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bud/graphs'
3
+ require 'bud/meta_algebra'
3
4
 
4
5
  module TraceCardinality
5
6
  state do
@@ -18,11 +19,12 @@ class VizHelper
18
19
  include Bud
19
20
  include TraceCardinality
20
21
 
21
- def initialize(tabinf, cycle, depends, rules, dir)
22
+ def initialize(tabinf, cycle, depends, rules, dir, provides)
22
23
  @t_tabinf = tabinf
23
24
  @t_cycle = cycle
24
25
  @t_depends = depends
25
26
  @t_rules = rules
27
+ @t_provides = provides
26
28
  @dir = dir
27
29
  super()
28
30
  end
@@ -59,21 +61,93 @@ end
59
61
 
60
62
 
61
63
  module VizUtil #:nodoc: all
62
- def graph_from_instance(bud_instance, viz_name, output_base, collapse=true, fmt=nil)
64
+ def self.ma_tables
65
+ # a craven, contemptible hack to grab the metatables.
66
+ estr = "class Foo\ninclude Bud\ninclude MetaAlgebra\ninclude MetaReports\nend"
67
+ eval(estr)
68
+ e = Foo.new
69
+ e.tables
70
+ end
71
+
72
+ def graph_from_instance(bud_instance, viz_name, output_base, collapse=true, fmt=nil, data=nil)
63
73
  tabinf = {}
64
74
  bud_instance.tables.each do |t|
65
75
  tab = t[0].to_s
66
76
  tabinf[tab] = t[1].class.to_s
67
77
  end
68
- write_graphs(tabinf, bud_instance.builtin_tables, bud_instance.t_cycle,
78
+
79
+ begins = get_paths(bud_instance)
80
+ bit = bud_instance.builtin_tables
81
+ VizUtil.ma_tables.each_pair{|k, v| bit[k] = v}
82
+
83
+ write_graphs(tabinf, bit, bud_instance.t_cycle,
69
84
  bud_instance.t_depends, bud_instance.t_rules, viz_name,
70
- output_base, fmt, collapse, bud_instance.meta_parser.depanalysis)
85
+ output_base, fmt, collapse, bud_instance.meta_parser.depanalysis, -1, nil,
86
+ get_labels(bud_instance), begins)
87
+ begins
88
+ end
89
+
90
+ def get_paths(bud_instance)
91
+ return {} unless bud_instance.respond_to? :a_preds
92
+ begins = {}
93
+ bud_instance.a_preds.each do |b|
94
+ begins[:start] ||= {}
95
+ begins[:start][b.path.split("|").last] = b.fullpath.split("|").last
96
+ begins[:finish] = {}
97
+ begins[:finish][b.fullpath.split("|").last] = true
98
+ end
99
+ begins
100
+ end
101
+
102
+ def get_labels(bud_instance)
103
+ return {} unless bud_instance.respond_to? :lps
104
+ # sort the paths. sort the paths to the same destination by length.
105
+ aps = {}
106
+ ap_interm = bud_instance.lps.sort do |a, b|
107
+ if a.to == b.to then
108
+ a.path.length <=> b.path.length
109
+ else
110
+ a <=> b
111
+ end
112
+ end
113
+ ap_interm.each do |a|
114
+ aps[a.to] ||= []
115
+ aps[a.to] << a.tag
116
+ end
117
+
118
+ # grab the lattice metadata
119
+ lub = {}
120
+ bud_instance.lub.each do |l|
121
+ lub[l.left] ||= {}
122
+ lub[l.left][l.right] = l.result
123
+ end
124
+
125
+ # b/c set union isn't working right
126
+ ap2 = {}
127
+ aps.each_pair do |k, v|
128
+ tmp = v.reduce({}) do |memo, i|
129
+ memo[:val] ||= :M
130
+ was = memo[:val]
131
+ if lub[memo[:val]][i]
132
+ if i == :N
133
+ memo[:val] = lub[i][memo[:val]]
134
+ else
135
+ memo[:val] = lub[memo[:val]][i]
136
+ end
137
+ else
138
+ puts "couldn't find #{memo[:val]} - #{i} in #{lub.inspect}"
139
+ end
140
+ memo
141
+ end
142
+ ap2[k] = [tmp, v]
143
+ end
144
+ ap2
71
145
  end
72
146
 
73
147
  def write_graphs(tabinf, builtin_tables, cycle, depends, rules, viz_name,
74
- output_base, fmt, collapse, depanalysis=nil, budtime=-1, card_info=nil)
148
+ output_base, fmt, collapse, depanalysis=nil, budtime=-1, card_info=nil, pathsto={}, begins = {})
75
149
  staging = "#{viz_name}.staging"
76
- gv = GraphGen.new(tabinf, builtin_tables, cycle, staging, budtime, collapse, card_info)
150
+ gv = GraphGen.new(tabinf, builtin_tables, cycle, staging, budtime, collapse, card_info, pathsto, begins)
77
151
  gv.process(depends)
78
152
  dump(rules, output_base, gv)
79
153
  gv.finish(depanalysis, fmt)
@@ -116,7 +190,6 @@ module VizUtil #:nodoc: all
116
190
  if !code[v[0]]
117
191
  code[v[0]] = ""
118
192
  end
119
- #code[v[0]] = "<br># RULE #{k}<br> " + code[v[0]] + "<br>" + v[1]
120
193
  code[v[0]] = "\n# RULE #{k}\n " + code[v[0]] + "\n" + v[1]
121
194
  end
122
195
  gv_obj.nodes.each_pair do |k, v|
@@ -213,7 +286,7 @@ END_JS
213
286
  end
214
287
 
215
288
  def get_meta2(dir)
216
- meta_tabs = {"t_table_info" => :tabinf, "t_table_schema" => :tabscm, "t_cycle" => :cycle, "t_depends" => :depends, "t_rules" => :rules}
289
+ meta_tabs = {"t_table_info" => :tabinf, "t_table_schema" => :tabscm, "t_cycle" => :cycle, "t_depends" => :depends, "t_rules" => :rules, "t_provides" => :provides}
217
290
  meta = {}
218
291
  data = []
219
292
 
@@ -227,7 +300,7 @@ END_JS
227
300
  tup = key[0]
228
301
  MessagePack.unpack(v).each {|val| tup << val}
229
302
  if meta_tabs[tab]
230
- raise "non-zero budtime. sure this is metadata?" if time != 0 and strict
303
+ raise "non-zero budtime.(tab=#{tab}, time=#{time}) sure this is metadata?" if time != 0 #and strict
231
304
  meta[meta_tabs[tab]] ||= []
232
305
  meta[meta_tabs[tab]] << tup
233
306
  #ret << tup
@@ -254,10 +327,19 @@ END_JS
254
327
  def start_table(dir, tab, time, schema)
255
328
  str = "#{dir}/#{tab}_#{time}.html"
256
329
  fout = File.new(str, "w")
257
-
258
330
  fout.puts "<html><title>#{tab} @ #{time}</title>"
259
331
  fout.puts "<table border=1>"
260
- fout.puts "<tr>" + schema.map{|s| "<th> #{s} </th>"}.join(" ") + "<tr>" unless schema.nil?
332
+ # issue with _snd schemas
333
+ if !schema.nil? and schema[0] == "c_bud_time"
334
+ fout.puts "<tr>"
335
+ if schema[1].length == 2 and schema[1][0].class == Array and schema[1][1].class == Array
336
+ fout.puts schema[1][0].map{|s| "<th> #{s} </th>"}.join(" ")
337
+ fout.puts schema[1][1].map{|s| "<th> #{s} </th>"}.join(" ")
338
+ else
339
+ fout.puts schema[1].map{|s| "<th> #{s} </th>"}.join(" ")
340
+ end
341
+ fout.puts "<tr>"
342
+ end
261
343
  fout.close
262
344
  return str
263
345
  end
data/lib/bud.rb CHANGED
@@ -20,6 +20,7 @@ require 'bud/deploy/threaddeploy'
20
20
  require 'bud/errors'
21
21
  require 'bud/joins'
22
22
  require 'bud/metrics'
23
+ require 'bud/meta_algebra'
23
24
  require 'bud/rtrace'
24
25
  require 'bud/server'
25
26
  require 'bud/state'
@@ -92,6 +93,15 @@ module Bud
92
93
  # * <tt>:metrics</tt> if true, dumps a hash of internal performance metrics
93
94
  # * controlling execution
94
95
  # * <tt>:tag</tt> a name for this instance, suitable for display during tracing and visualization
96
+ # * <tt>:channel_filter</tt> a code block that can be used to filter the
97
+ # network messages delivered to this Bud instance. At the start of each
98
+ # tick, the code block is invoked for every channel with any incoming
99
+ # messages; the code block is passed the name of the channel and an array
100
+ # containing the inbound messages. It should return a two-element array
101
+ # containing "accepted" and "postponed" messages, respectively. Accepted
102
+ # messages are delivered during this tick, and postponed messages are
103
+ # buffered and passed to the filter in subsequent ticks. Any messages that
104
+ # aren't in either array are dropped.
95
105
  # * storage configuration
96
106
  # * <tt>:dbm_dir</tt> filesystem directory to hold DBM-backed collections
97
107
  # * <tt>:dbm_truncate</tt> if true, DBM-backed collections are opened with +OTRUNC+
@@ -117,7 +127,7 @@ module Bud
117
127
  @inside_tick = false
118
128
  @tick_clock_time = nil
119
129
  @budtime = 0
120
- @inbound = []
130
+ @inbound = {}
121
131
  @done_bootstrap = false
122
132
  @joinstate = {} # joins are stateful, their state needs to be kept inside the Bud instance
123
133
  @instance_id = ILLEGAL_INSTANCE_ID # Assigned when we start running
@@ -187,15 +197,15 @@ module Bud
187
197
  # temp collections. Imported modules are rewritten during the import process;
188
198
  # we rewrite the main class associated with this Bud instance and any included
189
199
  # modules here. Note that we only rewrite each distinct Class once, and we
190
- # skip methods defined by the Bud (Ruby) module directly (since we can be sure
191
- # those won't reference Bloom modules).
200
+ # skip methods defined by the Bud (Ruby) module or the builtin Bloom programs
201
+ # (since we can be sure those won't need rewriting).
192
202
  def self.rewrite_local_methods(klass)
193
203
  @done_rewrite ||= {}
194
204
  return if @done_rewrite.has_key? klass.name
195
- return if klass.name == self.name # Skip methods defined in the Bud module
205
+ return if [self, DepAnalysis, Stratification].include? klass
196
206
 
197
207
  u = Unifier.new
198
- ref_expander = NestedRefRewriter.new(klass.bud_import_table)
208
+ ref_expander = NestedRefRewriter.new(klass)
199
209
  tmp_expander = TempExpander.new
200
210
  with_expander = WithExpander.new
201
211
  r2r = Ruby2Ruby.new
@@ -208,8 +218,8 @@ module Bud
208
218
  ast = with_expander.process(ast)
209
219
 
210
220
  if ref_expander.did_work or tmp_expander.did_work or with_expander.did_work
211
- new_source = r2r.process(ast)
212
- klass.module_eval new_source # Replace previous method def
221
+ new_src = r2r.process(ast)
222
+ klass.module_eval new_src # Replace previous method def
213
223
  end
214
224
 
215
225
  ref_expander.did_work = false
@@ -494,7 +504,7 @@ module Bud
494
504
  cb_id = nil
495
505
  schedule_and_wait do
496
506
  unless @tables.has_key? tbl_name
497
- raise Bud::Error, "no such table: #{tbl_name}"
507
+ raise Bud::Error, "no such collection: #{tbl_name}"
498
508
  end
499
509
 
500
510
  raise Bud::Error if @callbacks.has_key? @callback_id
@@ -650,7 +660,8 @@ module Bud
650
660
 
651
661
  def do_start_server
652
662
  @dsock = EventMachine::open_datagram_socket(@ip, @options[:port],
653
- BudServer, self)
663
+ BudServer, self,
664
+ @options[:channel_filter])
654
665
  @port = Socket.unpack_sockaddr_in(@dsock.get_sockname)[0]
655
666
  end
656
667
 
@@ -669,13 +680,13 @@ module Bud
669
680
  end
670
681
 
671
682
  def ip
672
- ip = options[:ext_ip] ? "#{@options[:ext_ip]}" : "#{@ip}"
683
+ options[:ext_ip] ? "#{@options[:ext_ip]}" : "#{@ip}"
673
684
  end
674
685
 
675
686
  def port
676
687
  return nil if @port.nil? and @options[:port] == 0 and not @options[:ext_port]
677
- return options[:ext_port] ? "#{@options[:ext_port]}" :
678
- (@port.nil? ? "#{@options[:port]}" : "#{@port}")
688
+ return @options[:ext_port] ? @options[:ext_port] :
689
+ (@port.nil? ? @options[:port] : @port)
679
690
  end
680
691
 
681
692
  # Returns the internal IP and port. See ip_port.
@@ -769,8 +780,10 @@ module Bud
769
780
  # directly into the storage of the appropriate local channel. The inbound
770
781
  # queue is cleared at the end of the tick.
771
782
  def receive_inbound
772
- @inbound.each do |msg|
773
- tables[msg[0].to_sym] << msg[1]
783
+ @inbound.each do |tbl_name, msg_buf|
784
+ msg_buf.each do |b|
785
+ tables[tbl_name] << b
786
+ end
774
787
  end
775
788
  end
776
789
 
@@ -840,7 +853,7 @@ module Bud
840
853
  unless new_e.class <= Bud::Error
841
854
  new_e = Bud::Error
842
855
  end
843
- raise new_e, "exception during Bud evaluation.\nException: #{e.inspect}.#{src_msg}"
856
+ raise new_e, "exception during Bud evaluation.\nException: #{e.inspect}\nLocation: #{e.backtrace.first}.#{src_msg}"
844
857
  end
845
858
  end
846
859
  @stratum_first_iter = false
@@ -870,7 +883,8 @@ module Bud
870
883
 
871
884
  def make_periodic_timer(name, period)
872
885
  EventMachine::PeriodicTimer.new(period) do
873
- @inbound << [name, [gen_id, Time.now]]
886
+ @inbound[name.to_sym] ||= []
887
+ @inbound[name.to_sym] << [gen_id, Time.now]
874
888
  tick_internal if @running_async
875
889
  end
876
890
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bud
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Peter Alvaro
@@ -274,6 +274,7 @@ files:
274
274
  - lib/bud/errors.rb
275
275
  - lib/bud/graphs.rb
276
276
  - lib/bud/joins.rb
277
+ - lib/bud/meta_algebra.rb
277
278
  - lib/bud/metrics.rb
278
279
  - lib/bud/monkeypatch.rb
279
280
  - lib/bud/rebl.rb