durable_rules 0.31.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ /* Drop in replacement for zmalloc.h in order to just use libc malloc without
2
+ * any wrappering. */
3
+
4
+ #ifndef ZMALLOC_H
5
+ #define ZMALLOC_H
6
+
7
+ #define zmalloc malloc
8
+ #define zrealloc realloc
9
+ #define zcalloc(x) calloc(x,1)
10
+ #define zfree free
11
+ #define zstrdup strdup
12
+
13
+ #endif
data/librb/durable.rb ADDED
@@ -0,0 +1,549 @@
1
+ require_relative "engine"
2
+ require_relative "interface"
3
+
4
+ module Durable
5
+ @@rulesets = {}
6
+ @@start_blocks = []
7
+
8
+ def self.run(ruleset_definitions = nil, databases = [{:host => 'localhost', :port => 6379, :password => nil}], start = nil)
9
+ main_host = Engine::Host.new ruleset_definitions, databases
10
+ start.call main_host if start
11
+ main_host.start!
12
+ Interface::Application.set_host main_host
13
+ Interface::Application.run!
14
+ end
15
+
16
+ def self.run_all(databases = [{:host => 'localhost', :port => 6379, :password => nil}])
17
+ main_host = Engine::Host.new @@rulesets, databases
18
+ for block in @@start_blocks
19
+ main_host.instance_exec main_host, &block
20
+ end
21
+ main_host.start!
22
+ Interface::Application.set_host main_host
23
+ Interface::Application.run!
24
+ end
25
+
26
+ def self.ruleset(name, &block)
27
+ ruleset = Ruleset.new name, block
28
+ @@rulesets[name] = ruleset.rules
29
+ @@start_blocks << ruleset.start if ruleset.start
30
+ end
31
+
32
+ def self.statechart(name, &block)
33
+ statechart = Statechart.new name, block
34
+ @@rulesets[name.to_s + "$state"] = statechart.states
35
+ @@start_blocks << statechart.start if statechart.start
36
+ end
37
+
38
+ def self.flowchart(name, &block)
39
+ flowchart = Flowchart.new name, block
40
+ @@rulesets[name.to_s + "$flow"] = flowchart.stages
41
+ @@start_blocks << flowchart.start if flowchart.start
42
+ end
43
+
44
+ class Arithmetic
45
+
46
+ def initialize(name, left = nil, sid = nil, op = nil, right = nil)
47
+ @name = name
48
+ @left = left
49
+ @sid = sid
50
+ @right = right
51
+ @op = op
52
+ end
53
+
54
+ def definition
55
+ if not @op
56
+ if @sid
57
+ {@name => {:name => @left, :id => @sid}}
58
+ else
59
+ {@name => @left}
60
+ end
61
+ else
62
+ new_definition = nil
63
+ left_definition = nil
64
+ if @left.kind_of? Arithmetic
65
+ left_definition = @left.definition
66
+ else
67
+ left_definition = {@name => @left}
68
+ end
69
+
70
+ righ_definition = @right
71
+ if @right.kind_of? Arithmetic
72
+ righ_definition = @right.definition
73
+ end
74
+
75
+ return {@op => {:$l => left_definition, :$r => righ_definition}}
76
+ end
77
+ end
78
+
79
+ def +(other)
80
+ set_right(:$add, other)
81
+ end
82
+
83
+ def -(other)
84
+ set_right(:$sub, other)
85
+ end
86
+
87
+ def *(other)
88
+ set_right(:$mul, other)
89
+ end
90
+
91
+ def /(other)
92
+ set_right(:$div, other)
93
+ end
94
+
95
+ def ==(other)
96
+ return Expression.new(@name, @left) == other
97
+ end
98
+
99
+ def !=(other)
100
+ return Expression.new(@name, @left) != other
101
+ end
102
+
103
+ def <(other)
104
+ return Expression.new(@name, @left) < other
105
+ end
106
+
107
+ def <=(other)
108
+ return Expression.new(@name, @left) <= other
109
+ end
110
+
111
+ def >(other)
112
+ return Expression.new(@name, @left) > other
113
+ end
114
+
115
+ def >=(other)
116
+ return Expression.new(@name, @left) >= other
117
+ end
118
+
119
+ def -@
120
+ return -Expression.new(@name, @left)
121
+ end
122
+
123
+ def +@
124
+ return +Expression.new(@name, @left)
125
+ end
126
+
127
+ def |(other)
128
+ return Expression.new(@name, @left) | other
129
+ end
130
+
131
+ def &(other)
132
+ return Expression.new(@name, @left) & other
133
+ end
134
+
135
+ def id(sid)
136
+ Arithmetic.new @name, @left, sid
137
+ end
138
+
139
+ private
140
+
141
+ def set_right(op, other)
142
+ if @right
143
+ @left = Arithmetic.new @name, @left, @sid, @op, @right
144
+ end
145
+
146
+ @op = op
147
+ @right = other
148
+ self
149
+ end
150
+
151
+ def default(name, value=nil)
152
+ @left = name
153
+ self
154
+ end
155
+
156
+ alias method_missing default
157
+
158
+ end
159
+
160
+ class Expression
161
+ attr_reader :__type, :__op
162
+ attr_accessor :__name
163
+
164
+ def initialize(type, left = nil)
165
+ @__type = type
166
+ @left = left
167
+ @right = nil
168
+ @definitions = nil
169
+ @__name = nil
170
+ end
171
+
172
+ def definition
173
+ new_definition = nil
174
+ if @__op == :$or || @__op == :$and
175
+ new_definition = {@__op => @definitions}
176
+ else
177
+ if not @left
178
+ raise ArgumentError, "Property for #{@__op} not defined"
179
+ end
180
+ righ_definition = @right
181
+ if (@right.kind_of? Expression) || (@right.kind_of? Arithmetic)
182
+ righ_definition = @right.definition
183
+ end
184
+
185
+ if @__op == :$eq
186
+ new_definition = {@left => righ_definition}
187
+ else
188
+ new_definition = {@__op => {@left => righ_definition}}
189
+ end
190
+ end
191
+
192
+ if @__type == :$s
193
+ {:$and => [new_definition, {:$s => 1}]}
194
+ else
195
+ new_definition
196
+ end
197
+ end
198
+
199
+ def ==(other)
200
+ @__op = :$eq
201
+ @right = other
202
+ self
203
+ end
204
+
205
+ def !=(other)
206
+ @__op = :$neq
207
+ @right = other
208
+ self
209
+ end
210
+
211
+ def <(other)
212
+ @__op = :$lt
213
+ @right = other
214
+ self
215
+ end
216
+
217
+ def <=(other)
218
+ @__op = :$lte
219
+ @right = other
220
+ self
221
+ end
222
+
223
+ def >(other)
224
+ @__op = :$gt
225
+ @right = other
226
+ self
227
+ end
228
+
229
+ def >=(other)
230
+ @__op = :$gte
231
+ @right = other
232
+ self
233
+ end
234
+
235
+ def -@
236
+ @__op = :$nex
237
+ @right = 1
238
+ self
239
+ end
240
+
241
+ def +@
242
+ @__op = :$ex
243
+ @right = 1
244
+ self
245
+ end
246
+
247
+ def |(other)
248
+ merge other, :$or
249
+ self
250
+ end
251
+
252
+ def &(other)
253
+ merge other, :$and
254
+ self
255
+ end
256
+
257
+ private
258
+
259
+ def default(name, value=nil)
260
+ @left = name
261
+ self
262
+ end
263
+
264
+ def merge(other, op)
265
+ raise ArgumentError, "Right type doesn't match" if other.__type != @__type
266
+ @definitions = [self.definition] if !@definitions
267
+ @__op = op
268
+ if other.__op && (other.__op == @__op)
269
+ @definitions + other.definition[@__op]
270
+ else
271
+ @definitions << other.definition
272
+ end
273
+ end
274
+
275
+ alias method_missing default
276
+
277
+ end
278
+
279
+ class Expressions
280
+ attr_reader :__type
281
+
282
+ def initialize(type, expressions)
283
+ @__type = type
284
+ @expressions = expressions
285
+ end
286
+
287
+ def definition
288
+ index = 0
289
+ new_definition = []
290
+ for expression in @expressions do
291
+ if (expression.kind_of? Expression) && expression.__name
292
+ expression_name = expression.__name
293
+ elsif @expressions.length == 1
294
+ expression_name = "m"
295
+ else
296
+ expression_name = "m_#{index}"
297
+ end
298
+ if expression.__type == :$all
299
+ new_definition << {expression_name + "$all" => expression.definition()}
300
+ elsif expression.__type == :$any
301
+ new_definition << {expression_name + "$any" => expression.definition()}
302
+ elsif expression.__type == :$not
303
+ new_definition << {expression_name + "$not" => expression.definition()[0]["m"]}
304
+ else
305
+ new_definition << {expression_name => expression.definition()}
306
+ end
307
+ index += 1
308
+ end
309
+ new_definition
310
+ end
311
+
312
+ end
313
+
314
+ class Closure
315
+
316
+ def s
317
+ Arithmetic.new(:$s)
318
+ end
319
+
320
+ private
321
+
322
+ def handle_property(name, value=nil)
323
+ name = name.to_s
324
+ if name.end_with? '='
325
+ name = name[0..-2]
326
+ value.__name = name
327
+ return value
328
+ else
329
+ Arithmetic.new(name)
330
+ end
331
+ end
332
+
333
+ alias method_missing handle_property
334
+ end
335
+
336
+ class Ruleset
337
+ attr_reader :name, :start
338
+ attr_accessor :rules
339
+
340
+ def initialize(name, block)
341
+ @name = name
342
+ @rules = {}
343
+ @rule_index = 0
344
+ @expression_index = 0
345
+ @start = nil
346
+ self.instance_exec &block
347
+ end
348
+
349
+ def when_all(*args, &block)
350
+ options, new_args = get_options(*args)
351
+ define_rule :all, Expressions.new(:$all, new_args).definition, options, &block
352
+ end
353
+
354
+ def when_any(*args, &block)
355
+ options, new_args = get_options(*args)
356
+ define_rule :any, Expressions.new(:$any, new_args).definition, options, &block
357
+ end
358
+
359
+ def all(*args)
360
+ Expressions.new :$all, args
361
+ end
362
+
363
+ def any(*args)
364
+ Expressions.new :$any, args
365
+ end
366
+
367
+ def none(*args)
368
+ Expressions.new :$not, args
369
+ end
370
+
371
+ def when_start(&block)
372
+ @start = block
373
+ self
374
+ end
375
+
376
+ def s
377
+ Arithmetic.new(:$s)
378
+ end
379
+
380
+ def m
381
+ Expression.new(:$m)
382
+ end
383
+
384
+ def c
385
+ Closure.new()
386
+ end
387
+
388
+ def count(value)
389
+ {:count => value}
390
+ end
391
+
392
+ def pri(value)
393
+ {:pri => value}
394
+ end
395
+
396
+ def span(value)
397
+ {:span => value}
398
+ end
399
+
400
+ def cap(value)
401
+ {:cap => value}
402
+ end
403
+
404
+ def timeout(name)
405
+ expression = Expression.new(:$m, :$t)
406
+ expression == name
407
+ end
408
+
409
+ protected
410
+
411
+ def get_options(*args)
412
+ options = {}
413
+ new_args = []
414
+ for arg in args do
415
+ if arg.kind_of? Hash
416
+ options = options.merge!(arg)
417
+ else
418
+ new_args << arg
419
+ end
420
+ end
421
+ return options, new_args
422
+ end
423
+
424
+ def define_rule(operator, expression_definition, options, &block)
425
+ index = @rule_index.to_s
426
+ @rule_index += 1
427
+ rule_name = "r_#{index}"
428
+ rule = nil
429
+ if block
430
+ run_lambda = -> c {
431
+ c.instance_exec c, &block
432
+ }
433
+ rule = operator ? {operator => expression_definition, :run => run_lambda} : {:run => run_lambda}
434
+ else
435
+ rule = operator ? {operator => expression_definition} : {}
436
+ end
437
+
438
+ if options.key? :count
439
+ rule["count"] = options[:count]
440
+ end
441
+
442
+ if options.key? :pri
443
+ rule["pri"] = options[:pri]
444
+ end
445
+
446
+ if options.key? :span
447
+ rule["span"] = options[:span]
448
+ end
449
+
450
+ if options.key? :cap
451
+ rule["cap"] = options[:cap]
452
+ end
453
+
454
+ @rules[rule_name] = rule
455
+ rule
456
+ end
457
+
458
+ private
459
+
460
+ def handle_property(name, value=nil)
461
+ return Arithmetic.new(name.to_s)
462
+ end
463
+
464
+ alias method_missing handle_property
465
+
466
+ end
467
+
468
+
469
+ class State < Ruleset
470
+
471
+ def initialize(name, block)
472
+ super name, block
473
+ end
474
+
475
+ def to(state_name, rule = nil, &block)
476
+ rule = define_rule(nil, nil, {}, &block) if !rule
477
+ rule[:to] = state_name
478
+ if block
479
+ rule[:run] = -> s {s.instance_exec(s, &block)}
480
+ end
481
+ self
482
+ end
483
+
484
+ def state(state_name, &block)
485
+ @rules[:$chart] = {} if (!@rules.key? :$chart)
486
+ if block
487
+ @rules[:$chart][state_name] = State.new(state_name, block).rules
488
+ else
489
+ @rules[:$chart][state_name] = {}
490
+ end
491
+ end
492
+
493
+ end
494
+
495
+ class Statechart
496
+ attr_reader :states, :start
497
+
498
+ def initialize(name, block)
499
+ @states = {}
500
+ self.instance_exec &block
501
+ end
502
+
503
+ def state(state_name, &block)
504
+ if block
505
+ states[state_name] = State.new(state_name, block).rules
506
+ else
507
+ states[state_name] = {}
508
+ end
509
+ end
510
+
511
+ def when_start(&block)
512
+ @start = block
513
+ self
514
+ end
515
+
516
+ end
517
+
518
+ class Flowchart < Ruleset
519
+ attr_reader :stages
520
+
521
+ def initialize(name, block)
522
+ @stages = {}
523
+ @current_stage = nil
524
+ super name, block
525
+ end
526
+
527
+ def to(stage_name, rule = nil)
528
+ if !rule
529
+ stages[@current_stage][:to] = stage_name
530
+ elsif rule.key? :all
531
+ stages[@current_stage][:to][stage_name] = {:all => rule[:all]}
532
+ else
533
+ stages[@current_stage][:to][stage_name] = {:any => rule[:any]}
534
+ end
535
+ end
536
+
537
+ def stage(stage_name, &block)
538
+ if block
539
+ @stages[stage_name] = {:run => -> s {s.instance_exec(s, &block)}, :to => {}}
540
+ else
541
+ @stages[stage_name] = {:to => {}}
542
+ end
543
+
544
+ @current_stage = stage_name
545
+ self
546
+ end
547
+ end
548
+
549
+ end