foxbat 0.2.4 → 0.2.5

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.
data/lib/em/connection.rb CHANGED
@@ -17,6 +17,14 @@ module EventMachine
17
17
  @netty_handler.write(data)
18
18
  end
19
19
 
20
+ def broadcast(data)
21
+ @netty_handler.write(data, true)
22
+ end
23
+
24
+ def send_file_data(path)
25
+ @netty_handler.send_file(path)
26
+ end
27
+
20
28
  def post_init; end
21
29
 
22
30
  def unbind; end
@@ -28,11 +36,7 @@ module EventMachine
28
36
  end
29
37
 
30
38
  def close_connection(after_writing=false)
31
- if after_writing
32
- @close_scheduled = true
33
- else
34
- @netty_handler.close
35
- end
39
+ @netty_handler.close
36
40
  end
37
41
 
38
42
  def close_connection_after_writing
@@ -44,7 +48,7 @@ module EventMachine
44
48
  end
45
49
 
46
50
  def comm_inactivity_timeout=(seconds)
47
- # todo
51
+ @netty_handler.set_read_timeout(seconds)
48
52
  end
49
53
 
50
54
  end
@@ -0,0 +1,210 @@
1
+ #--
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 Jul 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+ module EventMachine
27
+ module Deferrable
28
+ autoload :Pool, 'em/deferrable/pool'
29
+
30
+ # Specify a block to be executed if and when the Deferrable object receives
31
+ # a status of :succeeded. See #set_deferred_status for more information.
32
+ #
33
+ # Calling this method on a Deferrable object whose status is not yet known
34
+ # will cause the callback block to be stored on an internal list.
35
+ # If you call this method on a Deferrable whose status is :succeeded, the
36
+ # block will be executed immediately, receiving the parameters given to the
37
+ # prior #set_deferred_status call.
38
+ #
39
+ #--
40
+ # If there is no status, add a callback to an internal list.
41
+ # If status is succeeded, execute the callback immediately.
42
+ # If status is failed, do nothing.
43
+ #
44
+ def callback &block
45
+ return unless block
46
+ @deferred_status ||= :unknown
47
+ if @deferred_status == :succeeded
48
+ block.call(*@deferred_args)
49
+ elsif @deferred_status != :failed
50
+ @callbacks ||= []
51
+ @callbacks.unshift block # << block
52
+ end
53
+ self
54
+ end
55
+
56
+ # Cancels an outstanding callback to &block if any. Undoes the action of #callback.
57
+ #
58
+ def cancel_callback block
59
+ @callbacks ||= []
60
+ @callbacks.delete block
61
+ end
62
+
63
+ # Specify a block to be executed if and when the Deferrable object receives
64
+ # a status of :failed. See #set_deferred_status for more information.
65
+ #--
66
+ # If there is no status, add an errback to an internal list.
67
+ # If status is failed, execute the errback immediately.
68
+ # If status is succeeded, do nothing.
69
+ #
70
+ def errback &block
71
+ return unless block
72
+ @deferred_status ||= :unknown
73
+ if @deferred_status == :failed
74
+ block.call(*@deferred_args)
75
+ elsif @deferred_status != :succeeded
76
+ @errbacks ||= []
77
+ @errbacks.unshift block # << block
78
+ end
79
+ self
80
+ end
81
+
82
+ # Cancels an outstanding errback to &block if any. Undoes the action of #errback.
83
+ #
84
+ def cancel_errback block
85
+ @errbacks ||= []
86
+ @errbacks.delete block
87
+ end
88
+
89
+ # Sets the "disposition" (status) of the Deferrable object. See also the large set of
90
+ # sugarings for this method.
91
+ # Note that if you call this method without arguments,
92
+ # no arguments will be passed to the callback/errback.
93
+ # If the user has coded these with arguments, then the
94
+ # user code will throw an argument exception.
95
+ # Implementors of deferrable classes <b>must</b>
96
+ # document the arguments they will supply to user callbacks.
97
+ #
98
+ # OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
99
+ # on the INSIDE of a callback. This is very useful when a previously-registered
100
+ # callback wants to change the parameters that will be passed to subsequently-registered
101
+ # ones.
102
+ #
103
+ # You may give either :succeeded or :failed as the status argument.
104
+ #
105
+ # If you pass :succeeded, then all of the blocks passed to the object using the #callback
106
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
107
+ # passed to the object using #errback will be discarded.
108
+ #
109
+ # If you pass :failed, then all of the blocks passed to the object using the #errback
110
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
111
+ # passed to the object using # callback will be discarded.
112
+ #
113
+ # If you pass any arguments to #set_deferred_status in addition to the status argument,
114
+ # they will be passed as arguments to any callbacks or errbacks that are executed.
115
+ # It's your responsibility to ensure that the argument lists specified in your callbacks and
116
+ # errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise
117
+ # an ArgumentError.
118
+ #
119
+ #--
120
+ # We're shifting callbacks off and discarding them as we execute them.
121
+ # This is valid because by definition callbacks are executed no more than
122
+ # once. It also has the magic effect of permitting recursive calls, which
123
+ # means that a callback can call #set_deferred_status and change the parameters
124
+ # that will be sent to subsequent callbacks down the chain.
125
+ #
126
+ # Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion
127
+ # by Kirk Haines, to work around the memory leak bug that still exists in many Ruby
128
+ # versions.
129
+ #
130
+ # Changed 15Sep07: after processing callbacks or errbacks, CLEAR the other set of
131
+ # handlers. This gets us a little closer to the behavior of Twisted's "deferred,"
132
+ # which only allows status to be set once. Prior to making this change, it was possible
133
+ # to "succeed" a Deferrable (triggering its callbacks), and then immediately "fail" it,
134
+ # triggering its errbacks! That is clearly undesirable, but it's just as undesirable
135
+ # to raise an exception is status is set more than once on a Deferrable. The latter
136
+ # behavior would invalidate the idiom of resetting arguments by setting status from
137
+ # within a callback or errback, but more seriously it would cause spurious errors
138
+ # if a Deferrable was timed out and then an attempt was made to succeed it. See the
139
+ # comments under the new method #timeout.
140
+ #
141
+ def set_deferred_status status, *args
142
+ cancel_timeout
143
+ @errbacks ||= nil
144
+ @callbacks ||= nil
145
+ @deferred_status = status
146
+ @deferred_args = args
147
+ case @deferred_status
148
+ when :succeeded
149
+ if @callbacks
150
+ while cb = @callbacks.pop
151
+ cb.call(*@deferred_args)
152
+ end
153
+ end
154
+ @errbacks.clear if @errbacks
155
+ when :failed
156
+ if @errbacks
157
+ while eb = @errbacks.pop
158
+ eb.call(*@deferred_args)
159
+ end
160
+ end
161
+ @callbacks.clear if @callbacks
162
+ end
163
+ end
164
+
165
+
166
+ # Setting a timeout on a Deferrable causes it to go into the failed state after
167
+ # the Timeout expires (passing no arguments to the object's errbacks).
168
+ # Setting the status at any time prior to a call to the expiration of the timeout
169
+ # will cause the timer to be cancelled.
170
+ def timeout seconds, *args
171
+ cancel_timeout
172
+ me = self
173
+ @deferred_timeout = EventMachine::Timer.new(seconds) {me.fail(*args)}
174
+ self
175
+ end
176
+
177
+ # Cancels an outstanding timeout if any. Undoes the action of #timeout.
178
+ #
179
+ def cancel_timeout
180
+ @deferred_timeout ||= nil
181
+ if @deferred_timeout
182
+ @deferred_timeout.cancel
183
+ @deferred_timeout = nil
184
+ end
185
+ end
186
+
187
+
188
+ # Sugar for set_deferred_status(:succeeded, ...)
189
+ #
190
+ def succeed *args
191
+ set_deferred_status :succeeded, *args
192
+ end
193
+ alias set_deferred_success succeed
194
+
195
+ # Sugar for set_deferred_status(:failed, ...)
196
+ #
197
+ def fail *args
198
+ set_deferred_status :failed, *args
199
+ end
200
+ alias set_deferred_failure fail
201
+ end
202
+
203
+
204
+ # DefaultDeferrable is an otherwise empty class that includes Deferrable.
205
+ # This is very useful when you just need to return a Deferrable object
206
+ # as a way of communicating deferred status to some other part of a program.
207
+ class DefaultDeferrable
208
+ include Deferrable
209
+ end
210
+ end
data/lib/eventmachine.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  import java.lang.Long
2
2
  import java.util.concurrent.Executors
3
3
  import java.util.concurrent.TimeUnit
4
+ import org.jboss.netty.util.HashedWheelTimer
5
+
6
+ require 'foxbat/future'
4
7
 
5
8
  module EventMachine
6
9
 
7
- def self.start_server host, port=nil, handler=nil, *args, &block
10
+ def self.start_server(host, port=nil, handler=nil, *args, &block)
8
11
  s = Foxbat::Server.new(host, port, handler, args.first || {}, &block)
9
12
 
10
13
  @@servers ||= []
@@ -13,6 +16,11 @@ module EventMachine
13
16
  s.start(@@threadpool)
14
17
  end
15
18
 
19
+ def self.connect(host, port=nil, handler=nil, *args, &block)
20
+ c = Foxbat::Client.new(host, port, handler, args.first || {}, &block)
21
+ c.start(@@threadpool)
22
+ end
23
+
16
24
  # We're on the JVM- this does nothing!
17
25
  def self.epoll; end
18
26
  def self.kqueue; end
@@ -20,24 +28,37 @@ module EventMachine
20
28
  def self.run(blk=nil, tail=nil, &block)
21
29
  @alive = true
22
30
  @@threadpool = Executors.newCachedThreadPool
31
+ @@timer = HashedWheelTimer.new
23
32
 
24
33
  block.call
25
34
 
26
35
  @@threadpool.awaitTermination(Long::MAX_VALUE, TimeUnit::SECONDS)
27
36
  end
28
37
 
38
+ def self.add_timer(*args, &block)
39
+ timeout = args.shift
40
+ callable = args.shift || block
41
+ task = lambda { |t| callable.call }
42
+ @@timer.newTimeout(task, timeout, TimeUnit::SECONDS)
43
+ end
44
+
29
45
  def self.stop
30
46
  @@servers.each { |s| s.stop }
31
47
  @@threadpool.shutdown
48
+ @@timer.stop
32
49
  end
33
50
 
34
- def self.executor
35
- @@threadpool
51
+ def self.defer(op, callback)
52
+ Foxbat::Future.schedule(op, callback, @@threadpool)
36
53
  end
37
54
 
38
55
  def self.reactor_running?
39
56
  @alive
40
57
  end
41
58
 
59
+ def self.connection_count
60
+ @@servers.map { |s| s.connection_count }.reduce(:+)
61
+ end
62
+
42
63
  end
43
64
 
@@ -0,0 +1,29 @@
1
+ import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory
2
+ import org.jboss.netty.bootstrap.ClientBootstrap
3
+
4
+ module Foxbat
5
+
6
+ class Client
7
+
8
+ def initialize(host, port, klass, options, &block)
9
+ if options[:secure]
10
+ @context = Security.setup_ssl_client_context
11
+ end
12
+
13
+ @group = DefaultChannelGroup.new
14
+ @address = InetSocketAddress.new(host, port)
15
+ @pipeline = Pipeline.new(klass, @group, true, options, @context, &block)
16
+ end
17
+
18
+ def start(threadpool)
19
+ factory = NioClientSocketChannelFactory.new(threadpool, threadpool)
20
+ @bootstrap = ClientBootstrap.new(factory)
21
+ @bootstrap.setPipelineFactory(@pipeline)
22
+ @bootstrap.setOption("child.tcpNoDelay", true)
23
+ @bootstrap.setOption("child.keepAlive", true)
24
+ @bootstrap.connect(@address)
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,15 @@
1
+ import com.google.common.util.concurrent.ListenableFutureTask
2
+
3
+ module Foxbat
4
+
5
+ class Future
6
+
7
+ def self.schedule(op, cb, executor)
8
+ future = ListenableFutureTask.create(op)
9
+ future.addListener(cb, executor)
10
+ executor.submit(future)
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ import java.net.InetSocketAddress
2
+ import org.jboss.netty.channel.group.DefaultChannelGroup
3
+ require_relative 'pipeline'
4
+ require_relative 'security'
5
+
6
+ module Foxbat
7
+
8
+ class GenericConnection
9
+
10
+
11
+
12
+ def start; end
13
+ end
14
+
15
+ end
@@ -0,0 +1,104 @@
1
+ import org.jboss.netty.handler.codec.http.HttpRequestDecoder
2
+ import org.jboss.netty.handler.codec.http.HttpResponseEncoder
3
+ import org.jboss.netty.handler.codec.http.HttpContentCompressor
4
+ import org.jboss.netty.channel.Channels
5
+ import org.jboss.netty.channel.ChannelPipelineFactory
6
+ import org.jboss.netty.buffer.ChannelBuffers
7
+ import org.jboss.netty.handler.codec.http.DefaultHttpResponse
8
+ import org.jboss.netty.handler.codec.http.HttpResponseStatus
9
+ import org.jboss.netty.handler.codec.http.HttpVersion
10
+ import org.jboss.netty.handler.codec.http.HttpHeaders
11
+
12
+ require_relative 'server'
13
+
14
+ module Foxbat
15
+
16
+ class WebPipeline
17
+ include ChannelPipelineFactory
18
+
19
+ HANDLER = "handler"
20
+ ENCODER = "encoder"
21
+ DECODER = "decoder"
22
+ DEFLATER = "deflater"
23
+
24
+ def initialize(app)
25
+ @app = app
26
+ @handler = ReadTimeoutHandler.new(EM.timer, 10)
27
+ end
28
+
29
+ def getPipeline
30
+ pipeline = Channels.pipeline
31
+ pipeline.addLast(DECODER, HttpRequestDecoder.new)
32
+ pipeline.addLast(ENCODER, HttpResponseEncoder.new)
33
+ pipeline.addLast(DEFLATER, HttpContentCompressor.new)
34
+ pipeline.addLast(HANDLER, WebHandler.new(@app))
35
+ pipeline
36
+ end
37
+ end
38
+
39
+ class WebHandler < SimpleChannelUpstreamHandler
40
+
41
+ def initialize(app)
42
+ super()
43
+ @app = app
44
+ end
45
+
46
+ def messageReceived(ctx, e)
47
+ req = e.getMessage
48
+ env = to_rack(req)
49
+ val = @app.call(env)
50
+
51
+ resp = to_netty(val)
52
+ future = e.getChannel.write(resp)
53
+
54
+ listener = Object.new
55
+ def listener.operationComplete(f)
56
+ f.getChannel.close
57
+ end
58
+
59
+ future.addListener(listener)
60
+ end
61
+
62
+ private
63
+
64
+ def to_rack(req)
65
+ env = {}
66
+ env['REQUEST_METHOD'] = req.getMethod.toString
67
+
68
+ req.getHeaders.each do |h|
69
+ header = "HTTP_" + h.getKey.upcase.gsub("-", "_")
70
+ env[header] = h.getValue
71
+ end
72
+ env
73
+ end
74
+
75
+ CODES = {200 => HttpResponseStatus::OK}
76
+
77
+ def to_netty(resp)
78
+ code, headers, content = resp
79
+
80
+ netty_response = DefaultHttpResponse.new(HttpVersion::HTTP_1_1, CODES[code])
81
+ headers.each do |k,v|
82
+ netty_response.setHeader(k, v)
83
+ end
84
+
85
+ content = content.to_java_bytes if content.is_a?(String)
86
+ buf = ChannelBuffers.copiedBuffer(content)
87
+ netty_response.setContent(buf)
88
+ netty_response.setHeader('Content-Length', buf.writerIndex)
89
+ netty_response.setHeader('Server', 'Foxbat')
90
+ netty_response
91
+ end
92
+ end
93
+
94
+ class HttpServer < Server
95
+
96
+ def initialize(host, port, klass, options, &block)
97
+ super(host, port, klass, options, &block)
98
+ @pipeline.releaseExternalResources
99
+ @pipeline = WebPipeline.new(block)
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -1,5 +1,7 @@
1
+ import java.io.RandomAccessFile
1
2
  import java.nio.ByteBuffer
2
3
  import org.jboss.netty.buffer.ChannelBuffers
4
+ import org.jboss.netty.channel.DefaultFileRegion
3
5
  import org.jboss.netty.channel.SimpleChannelUpstreamHandler
4
6
 
5
7
  module Foxbat
@@ -13,21 +15,37 @@ module Foxbat
13
15
  super()
14
16
  end
15
17
 
16
- def write(data)
18
+ def write(data, broadcast=false)
17
19
  data = data.to_java_bytes if data.is_a?(String)
18
20
  buf = ChannelBuffers.copiedBuffer(data)
19
- @channel.write(buf)
21
+
22
+ recipient = broadcast ? @group : @channel
23
+ recipient.write(buf)
24
+ end
25
+
26
+ def send_file(path)
27
+ file_channel = RandomAccessFile.new(path, 'r').getChannel
28
+ region = DefaultFileRegion.new(file_channel, 0, file_channel.size, true)
29
+ @channel.write(region)
20
30
  end
21
31
 
22
32
  def close
23
33
  @channel.close
24
34
  end
25
35
 
36
+ def set_read_timeout(seconds)
37
+
38
+ end
39
+
26
40
  private
27
41
 
28
42
  def channelOpen(ctx, e)
29
43
  @group.add(e.getChannel)
30
44
  end
45
+
46
+ def channelClosed(ctx, e)
47
+ @group.remove(e.getChannel)
48
+ end
31
49
 
32
50
  def channelConnected(ctx, e)
33
51
  @pipeline = ctx.getPipeline
@@ -10,9 +10,19 @@ module Foxbat
10
10
  class Pipeline
11
11
  include ChannelPipelineFactory
12
12
 
13
- def initialize(handler, group, options={}, ssl_context=nil, &block)
13
+ HANDLER = "handler"
14
+ SSL_HANDLER = "ssl"
15
+
16
+ def initialize(handler, group, client, options={}, ssl_context=nil, &block)
14
17
  @options = options
15
18
  @handler = handler
19
+ @client_mode = client
20
+
21
+ if handler.class == Module
22
+ @handler = Class.new(EM::Connection)
23
+ @handler.send(:include, handler)
24
+ end
25
+
16
26
  @group = group
17
27
  @block = block
18
28
  @context = ssl_context
@@ -21,18 +31,19 @@ module Foxbat
21
31
  def getPipeline
22
32
  pipeline = Channels.pipeline
23
33
  if @context
24
- engine = Security.create_ssl_engine(@context)
25
- pipeline.addLast("ssl", SslHandler.new(engine))
34
+ engine = Security.create_ssl_engine(@context, @client_mode)
35
+ pipeline.addLast(SSL_HANDLER, SslHandler.new(engine))
26
36
  end
37
+
27
38
  h = @handler.new(@options)
28
39
  @block.call(h) if @block
29
40
  connection = NettyConnection.new(h, @group)
30
- pipeline.addLast("handler", connection)
41
+ pipeline.addLast(HANDLER, connection)
31
42
  pipeline
32
43
  end
33
44
 
34
45
  def releaseExternalResources
35
- p 'cleaning up factory...'
46
+ # todo
36
47
  end
37
48
  end
38
49
 
@@ -24,8 +24,9 @@ module Foxbat
24
24
  end
25
25
  fis.close
26
26
 
27
- kmf = KeyManagerFactory.getInstance('SunX509')
28
- tmf = TrustManagerFactory.getInstance('SunX509')
27
+ algorithm = KeyManagerFactory.getDefaultAlgorithm
28
+ kmf = KeyManagerFactory.getInstance(algorithm)
29
+ tmf = TrustManagerFactory.getInstance(algorithm)
29
30
 
30
31
  kmf.init(keystore, password)
31
32
  tmf.init(keystore)
@@ -43,10 +44,20 @@ module Foxbat
43
44
  context.init(kmf.getKeyManagers, tmf.getTrustManagers, nil)
44
45
  context
45
46
  end
46
-
47
- def self.create_ssl_engine(context)
48
- engine = context.createSSLEngine
49
- engine.setUseClientMode(false)
47
+
48
+ def self.setup_ssl_client_context
49
+ # keystore = KeyStore.getInstance(KeyStore.getDefaultType)
50
+ # context = SSLContext.getInstance('TLSv1')
51
+ # tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
52
+ # tmf.init(keystore)
53
+ # context.init(nil, nil, nil)
54
+ # context
55
+ SSLContext.getDefault
56
+ end
57
+
58
+ def self.create_ssl_engine(context, client=false)
59
+ context.createSSLEngine
60
+ engine.setUseClientMode(client)
50
61
  engine.setNeedClientAuth(false)
51
62
  engine
52
63
  end
data/lib/foxbat/server.rb CHANGED
@@ -3,12 +3,10 @@ import org.jboss.netty.channel.group.DefaultChannelGroup
3
3
  import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory
4
4
  import org.jboss.netty.bootstrap.ServerBootstrap
5
5
  require_relative 'pipeline'
6
- require_relative 'security'
7
6
 
8
7
  module Foxbat
9
8
 
10
9
  class Server
11
-
12
10
  def initialize(host, port, klass, options, &block)
13
11
  if options[:secure]
14
12
  @context = Security.setup_ssl_context(options[:keystore])
@@ -16,15 +14,21 @@ module Foxbat
16
14
 
17
15
  @group = DefaultChannelGroup.new
18
16
  @address = InetSocketAddress.new(host, port)
19
- @pipeline = Pipeline.new(klass, @group, options, @context, &block)
17
+ @pipeline = Pipeline.new(klass, @group, false, options, @context, &block)
20
18
  end
21
-
19
+
22
20
  def start(threadpool)
23
- @factory = NioServerSocketChannelFactory.new(threadpool, threadpool)
24
- @bootstrap = ServerBootstrap.new(@factory)
21
+ sp = java.util.concurrent.Executors.newSingleThreadExecutor
22
+ factory = NioServerSocketChannelFactory.new(sp, threadpool)
23
+ @bootstrap = ServerBootstrap.new(factory)
25
24
  @bootstrap.setPipelineFactory(@pipeline)
26
- @server_channel = @bootstrap.bind(@address)
27
- @group.add(@server_channel)
25
+ @bootstrap.setOption("child.tcpNoDelay", true)
26
+ server_channel = @bootstrap.bind(@address)
27
+ @group.add(server_channel)
28
+ end
29
+
30
+ def connection_count
31
+ @group.size - 1 # -1 to exclude the server's channel
28
32
  end
29
33
 
30
34
  def stop
@@ -1,3 +1,3 @@
1
1
  module Foxbat
2
- VERSION = '0.2.4'
2
+ VERSION = '0.2.5'
3
3
  end
data/lib/foxbat.rb CHANGED
@@ -1,45 +1,53 @@
1
1
  require 'java'
2
2
 
3
- NETTY_VERSION = '3.5.0.Final'
4
- JAR_SIZE = 1110903.0 # TODO: remove hard-coded jar size
5
-
6
- netty_jar = File.dirname(__FILE__) + "/netty-#{NETTY_VERSION}.jar"
3
+ unless Kernel.respond_to?(:require_relative)
4
+ module Kernel
5
+ def require_relative(path)
6
+ require File.join(File.dirname(caller[0]), path.to_str)
7
+ end
8
+ end
9
+ end
7
10
 
8
- if !File.exist?(netty_jar)
9
- puts "Couldn't find netty's JAR to load. Let's download it now."
11
+ def require_or_get(lib, version, ns)
12
+ jar = "#{lib}-#{version}.jar"
13
+ jarpath = File.dirname(__FILE__) + '/' + jar
14
+ if !File.exist?(jarpath)
15
+ puts "Couldn't find #{lib}, let's download it now."
10
16
 
11
- require 'net/http'
12
- f = open(netty_jar, 'w')
13
-
14
- Net::HTTP.start('search.maven.org') do |http|
15
-
16
- begin
17
- http.request_get("/remotecontent?filepath=io/netty/netty/#{NETTY_VERSION}/netty-#{NETTY_VERSION}.jar") do |resp|
18
- acc = 0
19
- resp.read_body do |segment|
20
- acc += segment.length
21
- percent = ((acc / JAR_SIZE) * 100).to_i
22
- print "Downloading netty #{NETTY_VERSION} from maven repository... [#{percent}%]\r"
23
- f.write(segment)
17
+ require 'net/http'
18
+ f = open(jarpath, 'w')
19
+
20
+ Net::HTTP.start('search.maven.org') do |http|
21
+
22
+ begin
23
+ http.request_get("/remotecontent?filepath=#{ns}/#{lib}/#{version}/#{jar}") do |resp|
24
+ puts "Downloading #{jar} from maven repository..."
25
+ resp.read_body do |segment|
26
+ f.write(segment)
27
+ end
28
+ puts "Done."
24
29
  end
25
- puts "\nDone. You shouldn't see me again :)"
30
+ ensure
31
+ f.close()
26
32
  end
27
- ensure
28
- f.close()
29
33
  end
30
34
  end
35
+
36
+ require jar
31
37
  end
32
38
 
33
- require 'netty-3.5.0.Final.jar'
39
+ require_or_get 'netty', '3.5.0.Final', 'io/netty'
40
+ require_or_get 'guava', '13.0.1', 'com/google/guava'
34
41
 
35
42
  require 'em/connection'
43
+ require 'em/deferrable'
36
44
  require 'em/periodic_timer'
37
45
  require 'em/timer'
46
+ require 'foxbat/client'
38
47
  require 'foxbat/server'
39
48
  require 'foxbat/version'
40
- require_relative 'eventmachine'
41
-
42
49
 
50
+ require_relative 'eventmachine'
43
51
 
44
52
  module EventMachine; end
45
53
 
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foxbat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-18 00:00:00.000000000 Z
12
+ date: 2012-11-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A drop-in replacement for EM, providing functionality missing from the
15
15
  Java port.
@@ -22,15 +22,21 @@ files:
22
22
  - lib/eventmachine.rb
23
23
  - lib/foxbat/barrier.rb
24
24
  - lib/foxbat/version.rb
25
+ - lib/foxbat/generic_connection.rb
26
+ - lib/foxbat/client.rb
25
27
  - lib/foxbat/server.rb
28
+ - lib/foxbat/http_server.rb
26
29
  - lib/foxbat/pipeline.rb
30
+ - lib/foxbat/future.rb
27
31
  - lib/foxbat/netty_connection.rb
28
32
  - lib/foxbat/security.rb
29
33
  - lib/netty-3.5.0.Final.jar
30
34
  - lib/foxbat.rb
31
35
  - lib/em/periodic_timer.rb
32
36
  - lib/em/timer.rb
37
+ - lib/em/deferrable.rb
33
38
  - lib/em/connection.rb
39
+ - lib/guava-13.0.1.jar
34
40
  homepage: http://github.com/m0wfo/foxbat
35
41
  licenses: []
36
42
  post_install_message: