bitgirder-platform 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/LICENSE.txt +176 -0
  2. data/bin/ensure-test-db +117 -0
  3. data/bin/install-mysql +375 -0
  4. data/bin/tomcat7 +569 -0
  5. data/lib/bitgirder/concurrent.rb +400 -0
  6. data/lib/bitgirder/core.rb +1235 -0
  7. data/lib/bitgirder/etl.rb +58 -0
  8. data/lib/bitgirder/event/file.rb +485 -0
  9. data/lib/bitgirder/event/logger/testing.rb +140 -0
  10. data/lib/bitgirder/event/logger.rb +137 -0
  11. data/lib/bitgirder/event/testing.rb +88 -0
  12. data/lib/bitgirder/http.rb +255 -0
  13. data/lib/bitgirder/io/testing.rb +33 -0
  14. data/lib/bitgirder/io.rb +959 -0
  15. data/lib/bitgirder/irb.rb +35 -0
  16. data/lib/bitgirder/mysql.rb +60 -0
  17. data/lib/bitgirder/ops/java.rb +117 -0
  18. data/lib/bitgirder/ops/ruby.rb +235 -0
  19. data/lib/bitgirder/testing.rb +152 -0
  20. data/lib/doc-gen0.rb +0 -0
  21. data/lib/doc-gen1.rb +0 -0
  22. data/lib/doc-gen10.rb +0 -0
  23. data/lib/doc-gen11.rb +0 -0
  24. data/lib/doc-gen12.rb +0 -0
  25. data/lib/doc-gen13.rb +0 -0
  26. data/lib/doc-gen14.rb +0 -0
  27. data/lib/doc-gen15.rb +0 -0
  28. data/lib/doc-gen16.rb +0 -0
  29. data/lib/doc-gen17.rb +14 -0
  30. data/lib/doc-gen18.rb +0 -0
  31. data/lib/doc-gen19.rb +0 -0
  32. data/lib/doc-gen2.rb +0 -0
  33. data/lib/doc-gen20.rb +182 -0
  34. data/lib/doc-gen21.rb +0 -0
  35. data/lib/doc-gen3.rb +0 -0
  36. data/lib/doc-gen4.rb +0 -0
  37. data/lib/doc-gen5.rb +0 -0
  38. data/lib/doc-gen6.rb +0 -0
  39. data/lib/doc-gen7.rb +0 -0
  40. data/lib/doc-gen8.rb +0 -0
  41. data/lib/doc-gen9.rb +0 -0
  42. data/lib/mingle/bincodec.rb +512 -0
  43. data/lib/mingle/codec.rb +54 -0
  44. data/lib/mingle/http.rb +156 -0
  45. data/lib/mingle/io/stream.rb +142 -0
  46. data/lib/mingle/io.rb +160 -0
  47. data/lib/mingle/json.rb +257 -0
  48. data/lib/mingle/service.rb +110 -0
  49. data/lib/mingle-em.rb +92 -0
  50. data/lib/mingle.rb +2917 -0
  51. metadata +100 -0
@@ -0,0 +1,137 @@
1
+ require 'bitgirder/core'
2
+ include BitGirder::Core
3
+
4
+ require 'thread'
5
+ require 'set'
6
+
7
+ module BitGirder
8
+ module Event
9
+
10
+ # Base library for BitGirder event logging. Generators of an event will call
11
+ # Engine.log_event, which dispatches the event to a dynamic set of listeners.
12
+ #
13
+ # Typically an application will create a single Engine instance during
14
+ # application startup, register some number of listeners, and then make the
15
+ # engine available to the rest of the application for logging events via
16
+ # Engine#log_event.
17
+ #
18
+ # Listeners registered with an Engine (see Engine#add_listener) should process
19
+ # events immediately and without blocking, since they execute in the call stack
20
+ # of the event producer. In particular, implementations which serialize events
21
+ # and perform IO (write to disk, send over a network) should be careful not to
22
+ # perform the IO directly upon receiving the event, but should delegate this to
23
+ # some ancillary thread.
24
+ #
25
+ # Events can be any ruby object. It is up to each listener to decide if/how to
26
+ # handle a given event.
27
+ #
28
+ # Development roadmap for this library:
29
+ #
30
+ # - Add skeletal listener implementations to simplify offloading IO or other
31
+ # intensive processing to a helper thread, as well as managing queuing
32
+ # policies and overload behavior (drop new events, drop old events, grow
33
+ # unbounded, etc).
34
+ #
35
+ module Logger
36
+
37
+ # An Engine coordinates dispatching of logged events a dynamic set of listeners.
38
+ # All methods are safe to call from concurrent threads.
39
+ class Engine < BitGirderClass
40
+
41
+ bg_attr :error_handler,
42
+ :required => false,
43
+ :description => <<-END_DESC
44
+ If set, this object will be called for various error methods to
45
+ which it responds.
46
+ END_DESC
47
+
48
+ # Creates a new instance with an empty listener set.
49
+ def impl_initialize # :nodoc:
50
+
51
+ super
52
+
53
+ @listeners = Set.new
54
+ @mut = Mutex.new
55
+ end
56
+
57
+ # In case we later decide to allow @mut to be optional or of varying
58
+ # implementations (not all apps which log will necessarily be threaded)
59
+ # we'll only need to modify this block to run code which should be
60
+ # threadsafe
61
+ private
62
+ def guarded( &blk )
63
+ @mut.synchronize( &blk )
64
+ end
65
+
66
+ # Gets the number of listeners managed by this engine
67
+ public
68
+ def listener_count
69
+ guarded { @listeners.size }
70
+ end
71
+
72
+ private
73
+ def listener_failed( l, ev, ex )
74
+
75
+ if @error_handler.respond_to?( :listener_failed )
76
+ @error_handler.listener_failed( l, ev, ex )
77
+ else
78
+ warn( ex, "Listener #{l} failed for event #{ev}" )
79
+ end
80
+ end
81
+
82
+ # Logs an event. After this method returns all listeners will have received
83
+ # the event.
84
+ public
85
+ def log_event( ev )
86
+
87
+ # Accumulate failures here so we can process them after releasing the
88
+ # lock
89
+ failures = []
90
+
91
+ guarded do
92
+ @listeners.each do |l|
93
+ begin
94
+ l.event_logged( ev )
95
+ rescue Exception => ex
96
+ failures << [ l, ev, ex ]
97
+ end
98
+ end
99
+ end
100
+
101
+ failures.each { |arr| listener_failed( *arr ) }
102
+ end
103
+
104
+ # Adds the given listener to this engine if it is not already present. All
105
+ # subsequent calls to log_event will dispatch to +l+ until a call is made to
106
+ # remove_listener
107
+ #
108
+ # This method returns +l+ to allow callers to chain listener
109
+ # creation/addition:
110
+ #
111
+ # list = eng.add_listener( SomeListener.new( ... ) )
112
+ #
113
+ public
114
+ def add_listener( l )
115
+
116
+ guarded do
117
+ if l.respond_to?( :event_logged )
118
+ @listeners << l unless @listeners.include?( l )
119
+ else
120
+ raise "Not an event listener: #{l} (#{l.class})"
121
+ end
122
+ end
123
+
124
+ l
125
+ end
126
+
127
+ # Removes +l+ from the dispatch set. It is not an error to call this
128
+ # method for an unregistered listener.
129
+ public
130
+ def remove_listener( l )
131
+ guarded { @listeners.delete( l ) }
132
+ end
133
+ end
134
+
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,88 @@
1
+ require 'bitgirder/core'
2
+ include BitGirder::Core
3
+
4
+ require 'bitgirder/io'
5
+ require 'bitgirder/io/testing'
6
+ include BitGirder::Io
7
+
8
+ module BitGirder
9
+ module Event
10
+ module Testing
11
+
12
+ class Int32Event < BitGirderClass
13
+
14
+ TYPE_CODE = 0x0001
15
+
16
+ bg_attr :i
17
+
18
+ def self.from_i( i ); self.new( :i => i ); end
19
+ end
20
+
21
+ class BufferEvent < BitGirderClass
22
+
23
+ TYPE_CODE = 0x0002
24
+
25
+ bg_attr :buf
26
+ end
27
+
28
+ class DelayEvent < BitGirderClass
29
+
30
+ bg_attr :delay # will be arg to sleep()
31
+ bg_attr :event
32
+ end
33
+
34
+ class TestCodec < BitGirderClass
35
+
36
+ include BitGirder::Io
37
+
38
+ private
39
+ def impl_initialize
40
+ @conv = BinaryConverter.new( :order => Io::ORDER_LITTLE_ENDIAN )
41
+ end
42
+
43
+ public
44
+ def encode_event( ev, io )
45
+
46
+ if ev.is_a?( DelayEvent )
47
+ sleep( ev.delay )
48
+ ev = ev.event
49
+ end
50
+
51
+ io.write( @conv.write_int32( ev.class::TYPE_CODE ) )
52
+
53
+ case ev
54
+ when Int32Event then io.write( @conv.write_int32( ev.i ) )
55
+ when BufferEvent then io.write( ev.buf )
56
+ else raise TypeError.new( "Unrecognized event: #{ev.class}" )
57
+ end
58
+ end
59
+
60
+ public
61
+ def decode_event( io, len )
62
+
63
+ ev_buf_len = len - 4
64
+
65
+ case cd = @conv.read_int32( io.read( 4 ) )
66
+ when Int32Event::TYPE_CODE
67
+ Int32Event.from_i( @conv.read_int32( io.read( 4 ) ) )
68
+ when BufferEvent::TYPE_CODE
69
+ BufferEvent.new( Io.read_full( io, ev_buf_len ) )
70
+ else raise sprintf( "Unexpected type code: %04x", cd )
71
+ end
72
+ end
73
+ end
74
+
75
+ def self.roundtrip( ev, codec )
76
+
77
+ io = Io::Testing.new_string_io
78
+ codec.encode_event( ev, io )
79
+
80
+ len = io.pos
81
+ io.seek( 0, IO::SEEK_SET )
82
+
83
+ codec.decode_event( io, len )
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,255 @@
1
+ require 'bitgirder/core'
2
+ include BitGirder::Core
3
+
4
+ require 'mingle'
5
+ include Mingle
6
+
7
+ require 'net/http'
8
+
9
+ module BitGirder
10
+ module Http
11
+
12
+ class HttpHeaders < BitGirderClass
13
+
14
+ private_class_method :new
15
+
16
+ bg_attr :pairs,
17
+ :default => [],
18
+ :processor => lambda { |pairs| pairs.sort!.freeze }
19
+
20
+ def self.as_header_name( nm )
21
+ nm.to_s.downcase
22
+ end
23
+
24
+ def self.as_header_val( val )
25
+ val.to_s.strip
26
+ end
27
+
28
+ def self.as_header_val_list( val )
29
+
30
+ case val
31
+
32
+ when Array, MingleList
33
+ val.empty? ? [ "" ] : val.map { |v| self.as_header_val( v ) }
34
+
35
+ else [ self.as_header_val( val ) ]
36
+ end
37
+ end
38
+
39
+ map_instance_of( Hash ) do |h|
40
+
41
+ pairs = {}
42
+
43
+ h.each_pair do |k, v|
44
+ arr = ( pairs[ self.as_header_name( k ) ] ||= [] )
45
+ arr.push( *( self.as_header_val_list( v ) ) )
46
+ end
47
+
48
+ self.send( :new, :pairs => pairs.to_a )
49
+ end
50
+
51
+ map_instance_of( Array ) do |arr|
52
+
53
+ pairs = arr.map do |pair|
54
+
55
+ if pair.size == 2
56
+ [ self.as_header_name( pair[ 0 ] ),
57
+ self.as_header_val_list( pair[ 1 ] ) ]
58
+ else
59
+ raise "Not a http header pair: #{pair.inspect}"
60
+ end
61
+ end
62
+
63
+ self.send( :new, :pairs => pairs )
64
+ end
65
+
66
+ map_instance_of( Net::HTTPHeader ) do |hdrs|
67
+
68
+ pairs = []
69
+ hdrs.each_name { |nm| pairs << [ nm.downcase, hdrs.get_fields( nm ) ] }
70
+
71
+ self.send( :new, :pairs => pairs )
72
+ end
73
+
74
+ public
75
+ def to_mingle_struct
76
+
77
+ MingleStruct.new(
78
+ :type => :"bitgirder:http@v1/HttpHeaders",
79
+ :fields => { :pairs => @pairs.map { |p| MingleList.new( p ) } }
80
+ )
81
+ end
82
+
83
+ def self.from_mingle_struct( ms )
84
+ self.as_instance( ( ms[ :pairs ] || [] ).to_a )
85
+ end
86
+ end
87
+
88
+ class HttpEndpoint < BitGirderClass
89
+
90
+ bg_attr :host, :required => false
91
+ bg_attr :port, :required => false
92
+ bg_attr :is_ssl, :required => false
93
+
94
+ map_instance_of( Net::HTTP ) do |http|
95
+
96
+ new(
97
+ :host => http.address,
98
+ :port => http.port,
99
+ :is_ssl => http.use_ssl?
100
+ )
101
+ end
102
+
103
+ def to_mingle_struct
104
+
105
+ MingleStruct.new(
106
+ :type => :"bitgirder:http@v1/HttpEndpoint",
107
+ :fields => {
108
+ :host => @host,
109
+ :port => @port,
110
+ :is_ssl => @is_ssl
111
+ }
112
+ )
113
+ end
114
+
115
+ def self.from_mingle_struct( ms )
116
+
117
+ self.new(
118
+ :host => ms.fields.get_string( :host ),
119
+ :port => ms.fields.get_int( :port ),
120
+ :is_ssl => ms.fields.get_boolean( :is_ssl )
121
+ )
122
+ end
123
+ end
124
+
125
+ PROC_TO_BIN = lambda { |b|
126
+ RubyVersions.when_19x( b ) { b.encode( Encoding::BINARY ) }
127
+ }
128
+
129
+ class HttpRequest < BitGirderClass
130
+
131
+ bg_attr :headers, :processor => HttpHeaders, :required => false
132
+ bg_attr :path, :required => false
133
+ bg_attr :body, :processor => PROC_TO_BIN, :required => false
134
+
135
+ def to_mingle_struct
136
+
137
+ MingleStruct.new(
138
+ :type => :"bitgirder:http@v1/HttpRequest",
139
+ :fields => {
140
+ :headers => @headers ? @headers.to_mingle_struct : nil,
141
+ :path => @path,
142
+ :body => @body ? MingleBuffer.new( @body ) : nil
143
+ }
144
+ )
145
+ end
146
+
147
+ def self.from_mingle_struct( ms )
148
+
149
+ mg_hdrs, mg_body = ms[ :headers ], ms[ :body ]
150
+
151
+ self.new(
152
+ :headers =>
153
+ mg_hdrs ? HttpHeaders.from_mingle_struct( mg_hdrs ) : nil,
154
+ :path => ms.fields.get_string( :path ),
155
+ :body => mg_body ? mg_body.buf : nil
156
+ )
157
+ end
158
+ end
159
+
160
+ class HttpStatus < BitGirderClass
161
+
162
+ bg_attr :code
163
+ bg_attr :message
164
+ bg_attr :version
165
+
166
+ map_instance_of( Net::HTTPResponse ) do |resp|
167
+
168
+ ver =
169
+ if ( ver_base = resp.http_version ).start_with?( "HTTP/" )
170
+ ver_base
171
+ else
172
+ "HTTP/#{ver_base}"
173
+ end
174
+
175
+ self.new(
176
+ :message => resp.message, :code => resp.code, :version => ver )
177
+ end
178
+
179
+ public
180
+ def to_mingle_struct
181
+ MingleStruct.new(
182
+ :type => :"bitgirder:http@v1/HttpStatus",
183
+ :fields => {
184
+ :code => @code,
185
+ :message => @message,
186
+ :version => @version
187
+ }
188
+ )
189
+ end
190
+
191
+ def self.from_mingle_struct( ms )
192
+
193
+ self.new(
194
+ :code => ms[ :code ].to_i,
195
+ :message => ms[ :message ].to_s,
196
+ :version => ms[ :version ].to_s
197
+ )
198
+ end
199
+ end
200
+
201
+ class HttpResponse < BitGirderClass
202
+
203
+ bg_attr :status, :processor => HttpStatus, :required => false
204
+ bg_attr :headers, :processor => HttpHeaders, :required => false
205
+ bg_attr :body, :processor => PROC_TO_BIN, :required => false
206
+
207
+ def self.from_net_http_response( resp, opts = {} )
208
+
209
+ not_nil( resp, :resp )
210
+ not_nil( opts, :opts )
211
+
212
+ log_body = opts[ :log_body ]
213
+
214
+ attrs = {
215
+ :status => HttpStatus.as_instance( resp ),
216
+ :headers => HttpHeaders.as_instance( resp )
217
+ }
218
+
219
+ if opts[ :log_body ] && resp.class.body_permitted?
220
+ attrs[ :body ] = resp.body
221
+ end
222
+
223
+ new( attrs )
224
+ end
225
+
226
+ map_instance_of( Net::HTTPResponse ) do |resp|
227
+ self.from_net_http_response( resp, :log_body => false )
228
+ end
229
+
230
+ def to_mingle_struct
231
+
232
+ MingleStruct.new(
233
+ :type => :"bitgirder:http@v1/HttpResponse",
234
+ :fields => {
235
+ :status => @status ? @status.to_mingle_struct : nil,
236
+ :headers => @headers ? @headers.to_mingle_struct : nil,
237
+ :body => @body ? MingleBuffer.new( body ) : nil
238
+ }
239
+ )
240
+ end
241
+
242
+ def self.from_mingle_struct( ms )
243
+
244
+ stat, hdrs, body = ms[ :status ], ms[ :headers ], ms[ :body ]
245
+
246
+ self.new(
247
+ :status => stat ? HttpStatus.from_mingle_struct( stat ) : nil,
248
+ :headers => hdrs ? HttpHeaders.from_mingle_struct( hdrs ) : nil,
249
+ :body => body ? body.buf : nil
250
+ )
251
+ end
252
+ end
253
+
254
+ end
255
+ end
@@ -0,0 +1,33 @@
1
+ require 'bitgirder/core'
2
+ require 'stringio'
3
+
4
+ module BitGirder
5
+ module Io
6
+
7
+ module Testing
8
+
9
+ [ :force_encoding, :encode, :encode! ].each do |meth|
10
+ define_method( :"opt_#{meth}" ) do |s, *argv|
11
+ RubyVersions.when_19x( s ) { |s| s.send( meth, *argv ) }
12
+ end
13
+ end
14
+
15
+ def new_string_io( str = "" )
16
+ RubyVersions.when_19x( StringIO.new( str ) ) do |io|
17
+ io.set_encoding( "binary" )
18
+ end
19
+ end
20
+
21
+ module_function :new_string_io
22
+
23
+ def rand_buf( len )
24
+
25
+ len = len.bytes if len.is_a?( DataSize )
26
+ File.open( "/dev/random", "rb" ) { |io| Io.read_full( io, len ) }
27
+ end
28
+
29
+ module_function :rand_buf
30
+ end
31
+
32
+ end
33
+ end