plezi 0.7.7 → 0.8.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +3 -3
  4. data/lib/plezi.rb +35 -36
  5. data/lib/plezi/common/cache.rb +94 -0
  6. data/lib/plezi/{base → common}/dsl.rb +87 -68
  7. data/lib/plezi/{base → common}/logging.rb +15 -15
  8. data/lib/plezi/eventmachine/connection.rb +192 -0
  9. data/lib/plezi/eventmachine/em.rb +95 -0
  10. data/lib/plezi/eventmachine/io.rb +265 -0
  11. data/lib/plezi/eventmachine/protocol.rb +54 -0
  12. data/lib/plezi/eventmachine/queue.rb +51 -0
  13. data/lib/plezi/eventmachine/ssl_connection.rb +138 -0
  14. data/lib/plezi/eventmachine/timers.rb +117 -0
  15. data/lib/plezi/eventmachine/workers.rb +35 -0
  16. data/lib/plezi/handlers/http_host.rb +4 -4
  17. data/lib/plezi/handlers/magic_helpers.rb +1 -21
  18. data/lib/plezi/handlers/route.rb +3 -3
  19. data/lib/plezi/server/{helpers/http.rb → http.rb} +1 -57
  20. data/lib/plezi/server/{protocols/http_protocol.rb → http_protocol.rb} +18 -35
  21. data/lib/plezi/server/{protocols/http_request.rb → http_request.rb} +1 -1
  22. data/lib/plezi/server/{protocols/http_response.rb → http_response.rb} +45 -22
  23. data/lib/plezi/server/{helpers/mime_types.rb → mime_types.rb} +0 -0
  24. data/lib/plezi/server/{protocols/websocket.rb → websocket.rb} +34 -37
  25. data/lib/plezi/server/{protocols/ws_response.rb → ws_response.rb} +37 -19
  26. data/lib/plezi/version.rb +1 -1
  27. data/plezi.gemspec +3 -3
  28. data/resources/config.ru +9 -11
  29. metadata +27 -30
  30. data/lib/plezi/base/cache.rb +0 -89
  31. data/lib/plezi/base/connections.rb +0 -33
  32. data/lib/plezi/base/engine.rb +0 -77
  33. data/lib/plezi/base/events.rb +0 -93
  34. data/lib/plezi/base/io_reactor.rb +0 -62
  35. data/lib/plezi/base/rack_app.rb +0 -89
  36. data/lib/plezi/base/services.rb +0 -57
  37. data/lib/plezi/base/timers.rb +0 -71
  38. data/lib/plezi/server/README.md +0 -33
  39. data/lib/plezi/server/services/basic_service.rb +0 -224
  40. data/lib/plezi/server/services/no_service.rb +0 -196
  41. data/lib/plezi/server/services/ssl_service.rb +0 -193
@@ -21,22 +21,53 @@ module Plezi
21
21
  @request, @service = request,request.service
22
22
  end
23
23
 
24
- # pushes data to the body of the response. this is the preffered way to add data to the response.
24
+ # sends data through the websocket connection in a non-blocking way.
25
+ #
26
+ # Plezi will try a best guess at the type of the data (binary vs. clear text).
27
+ #
28
+ # This should be the preferred way.
25
29
  def << str
26
30
  service.send_nonblock self.class.frame_data(str.dup)
27
31
  self
28
32
  end
29
33
 
30
- # sends the response object. headers will be frozen (they can only be sent at the head of the response).
34
+ # sends data through the websocket connection in a blocking way.
35
+ #
36
+ # Plezi will try a best guess at the type of the data (binary vs. clear text).
31
37
  #
32
- # the response will remain open for more data to be sent through (using `response << data` and `response.send`).
33
38
  def send str
34
- service.send_nonblock self.class.frame_data(str.dup)
39
+ service.send self.class.frame_data(str.dup)
40
+ self
41
+ end
42
+ # sends binary data through the websocket connection in a blocking way.
43
+ #
44
+ def binsend str
45
+ service.send self.class.frame_data(str.dup, 2)
46
+ self
47
+ end
48
+ # sends clear text data through the websocket connection in a blocking way.
49
+ #
50
+ def txtsend str
51
+ service.send self.class.frame_data(str.dup, 1)
52
+ self
35
53
  end
36
54
 
55
+
37
56
  # makes sure any data held in the buffer is actually sent.
38
57
  def flush
39
58
  service.flush
59
+ self
60
+ end
61
+
62
+ # pings the connection
63
+ def ping
64
+ service.send_nonblock self.class.frame_data('', 9)
65
+ self
66
+ end
67
+ # pings the connection
68
+ def pong
69
+ service.send_nonblock self.class.frame_data('', 10)
70
+ self
40
71
  end
41
72
 
42
73
  # sends any pending data and closes the connection.
@@ -49,10 +80,10 @@ module Plezi
49
80
  def self.frame_data data, op_code = nil, fin = true
50
81
  # set up variables
51
82
  frame = ''.force_encoding('binary')
52
- op_code ||= data.encoding.name == 'UTF-8' ? 1 : 2
83
+ op_code ||= (data.encoding.name == 'UTF-8' ? 1 : 2)
53
84
  data.force_encoding('binary')
54
85
 
55
- # fragment big data chuncks into smaller frames
86
+ # fragment big data chuncks into smaller frames - op-code reset for 0 for all future frames.
56
87
  [frame << frame_data(data.slice!(0..1048576), op_code, false), op_code = 0] while data.length > 1048576
57
88
 
58
89
  # apply extenetions to the frame
@@ -77,16 +108,3 @@ module Plezi
77
108
  end
78
109
  end
79
110
  end
80
-
81
-
82
- ######
83
- ## example requests
84
-
85
- # GET / HTTP/1.1
86
- # Host: localhost:2000
87
- # Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
88
- # Cookie: user_token=2INa32_vDgx8Aa1qe43oILELpSdIe9xwmT8GTWjkS-w
89
- # User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25
90
- # Accept-Language: en-us
91
- # Accept-Encoding: gzip, deflate
92
- # Connection: keep-alive
@@ -1,3 +1,3 @@
1
1
  module Plezi
2
- VERSION = "0.7.7"
2
+ VERSION = "0.8.1"
3
3
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Plezi::VERSION
9
9
  spec.authors = ["Boaz Segev"]
10
10
  spec.email = ['boaz@2be.co.il']
11
- spec.summary = %q{The Ruby Framework for real time web-apps, with Websockets, REST and HTTP streaming support.}
12
- spec.description = %q{Plezi is a Rack free Ruby Framework for real time web-apps, with native Websocket, HTTP streaming, and REST routing support.}
11
+ spec.summary = %q{Plezi is the native Ruby Framework for real time web-apps, with Websockets, RESTful routing and HTTP streaming support.}
12
+ spec.description = %q{Plezi is the native Ruby Framework for real time web-apps, with Websockets, RESTful routing and HTTP streaming support.}
13
13
  spec.homepage = "http://boazsegev.github.io/plezi/"
14
14
  spec.license = "MIT"
15
15
 
@@ -22,6 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
 
24
24
  # spec.post_install_message = "This update might break existing code - please review ChangeLog.md before upgrading any apps."
25
- spec.post_install_message = "Thank you for installing Plezi, the Ruby Framework for real time web-apps."
25
+ spec.post_install_message = "Thank you for installing Plezi, the native Ruby Framework for real time web-apps."
26
26
 
27
27
  end
@@ -22,18 +22,16 @@
22
22
  # 2. you have better control over Middleware then you could have with Plezi.
23
23
  # ("wait", you might say, "there is no Middleware in Plezi!"... "Ahhh", I will answer, "so much to discover...")
24
24
 
25
-
26
- working_dir = ::File.expand_path(Dir.pwd)
27
- app_path = ::File.expand_path(File.join(".."), __FILE__)
28
- app_file_name = app_path.split(/[\\\/]/).last + ".rb"
29
-
30
- # # make sure plezi doesn't set up sockets nor starts the event cycle.
31
25
  PLEZI_ON_RACK = true
32
26
 
33
- #load the Plezi application file
34
- Dir.chdir app_path
35
- require File.join(app_path, app_file_name)
27
+ # load all framework and gems
28
+ load ::File.expand_path(File.join("..", "environment.rb"), __FILE__)
29
+
30
+ # set up the routes
31
+ load ::File.expand_path(File.join("..", "routes.rb"), __FILE__)
36
32
 
37
- Dir.chdir working_dir
33
+ # start the plezi EM, to make sure that the plezi async code doesn't break.
34
+ Plezi::EventMachine.start Plezi.max_threads
38
35
 
39
- run Plezi
36
+ # run the Rack app
37
+ run Plezi::DSL
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plezi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-23 00:00:00.000000000 Z
11
+ date: 2015-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
- description: Plezi is a Rack free Ruby Framework for real time web-apps, with native
42
- Websocket, HTTP streaming, and REST routing support.
41
+ description: Plezi is the native Ruby Framework for real time web-apps, with Websockets,
42
+ RESTful routing and HTTP streaming support.
43
43
  email:
44
44
  - boaz@2be.co.il
45
45
  executables:
@@ -56,16 +56,17 @@ files:
56
56
  - TODO.md
57
57
  - bin/plezi
58
58
  - lib/plezi.rb
59
- - lib/plezi/base/cache.rb
60
- - lib/plezi/base/connections.rb
61
- - lib/plezi/base/dsl.rb
62
- - lib/plezi/base/engine.rb
63
- - lib/plezi/base/events.rb
64
- - lib/plezi/base/io_reactor.rb
65
- - lib/plezi/base/logging.rb
66
- - lib/plezi/base/rack_app.rb
67
- - lib/plezi/base/services.rb
68
- - lib/plezi/base/timers.rb
59
+ - lib/plezi/common/cache.rb
60
+ - lib/plezi/common/dsl.rb
61
+ - lib/plezi/common/logging.rb
62
+ - lib/plezi/eventmachine/connection.rb
63
+ - lib/plezi/eventmachine/em.rb
64
+ - lib/plezi/eventmachine/io.rb
65
+ - lib/plezi/eventmachine/protocol.rb
66
+ - lib/plezi/eventmachine/queue.rb
67
+ - lib/plezi/eventmachine/ssl_connection.rb
68
+ - lib/plezi/eventmachine/timers.rb
69
+ - lib/plezi/eventmachine/workers.rb
69
70
  - lib/plezi/handlers/controller_magic.rb
70
71
  - lib/plezi/handlers/http_echo.rb
71
72
  - lib/plezi/handlers/http_host.rb
@@ -73,17 +74,13 @@ files:
73
74
  - lib/plezi/handlers/magic_helpers.rb
74
75
  - lib/plezi/handlers/route.rb
75
76
  - lib/plezi/handlers/stubs.rb
76
- - lib/plezi/server/README.md
77
- - lib/plezi/server/helpers/http.rb
78
- - lib/plezi/server/helpers/mime_types.rb
79
- - lib/plezi/server/protocols/http_protocol.rb
80
- - lib/plezi/server/protocols/http_request.rb
81
- - lib/plezi/server/protocols/http_response.rb
82
- - lib/plezi/server/protocols/websocket.rb
83
- - lib/plezi/server/protocols/ws_response.rb
84
- - lib/plezi/server/services/basic_service.rb
85
- - lib/plezi/server/services/no_service.rb
86
- - lib/plezi/server/services/ssl_service.rb
77
+ - lib/plezi/server/http.rb
78
+ - lib/plezi/server/http_protocol.rb
79
+ - lib/plezi/server/http_request.rb
80
+ - lib/plezi/server/http_response.rb
81
+ - lib/plezi/server/mime_types.rb
82
+ - lib/plezi/server/websocket.rb
83
+ - lib/plezi/server/ws_response.rb
87
84
  - lib/plezi/version.rb
88
85
  - plezi.gemspec
89
86
  - resources/404.erb
@@ -116,8 +113,8 @@ homepage: http://boazsegev.github.io/plezi/
116
113
  licenses:
117
114
  - MIT
118
115
  metadata: {}
119
- post_install_message: Thank you for installing Plezi, the Ruby Framework for real
120
- time web-apps.
116
+ post_install_message: Thank you for installing Plezi, the native Ruby Framework for
117
+ real time web-apps.
121
118
  rdoc_options: []
122
119
  require_paths:
123
120
  - lib
@@ -133,9 +130,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
130
  version: '0'
134
131
  requirements: []
135
132
  rubyforge_project:
136
- rubygems_version: 2.4.6
133
+ rubygems_version: 2.4.7
137
134
  signing_key:
138
135
  specification_version: 4
139
- summary: The Ruby Framework for real time web-apps, with Websockets, REST and HTTP
140
- streaming support.
136
+ summary: Plezi is the native Ruby Framework for real time web-apps, with Websockets,
137
+ RESTful routing and HTTP streaming support.
141
138
  test_files: []
@@ -1,89 +0,0 @@
1
-
2
- module Plezi
3
-
4
- # File and Object Caching for Plezi
5
- module_function
6
- # contains the cached data, in the format: CACHE_STORE["filename"] = CacheObject
7
- CACHE_STORE = {}
8
- LOCK = Mutex.new
9
- CACHABLE = %w{cache object slim haml css map js html scss sass coffee txt xml json yaml rb}
10
-
11
- @cache_to_disk = true
12
-
13
- # this class holds cached objects (data and modification times)
14
- class CacheObject
15
- # Cached attributes
16
- attr_accessor :data, :mtime
17
-
18
- # initialize a Cached object
19
- def initialize d = nil, t = Time.now
20
- @data, @mtime = d, t
21
- end
22
- end
23
-
24
- # load the file from the cache (if exists) or the file system (if it doesn't)
25
- def load_file filename
26
- cached?(filename) ? get_cached(filename) : reload_file(filename)
27
- end
28
- # review a file's modification time
29
- def file_mtime filename
30
- return CACHE_STORE[filename].mtime if cached?(filename)
31
- File.mtime(filename)
32
- end
33
-
34
- # force a file onto the cache (only if it is cachable - otherwise will load the file but will not cache it).
35
- def reload_file filename
36
- if CACHABLE.include? filename.match(/\.([^\.]+)$/)[1]
37
- return cache_data filename, IO.read(filename), File.mtime(filename)
38
- else
39
- return IO.read(filename)
40
- end
41
- end
42
- # places data into the cache, and attempts to save the data to a file name.
43
- def save_file filename, data, save_to_disk = false
44
- cache_data filename, data if CACHABLE.include? filename.match(/\.([^\.]+)$/)[1]
45
- begin
46
- IO.write filename, data if save_to_disk
47
- rescue Exception => e
48
- Plezi.warn("File couldn't be written (#{filename}) - file system error?")
49
- end
50
- data
51
- end
52
-
53
- # places data into the cache, under an identifier ( file name ).
54
- def cache_data filename, data, mtime = Time.now
55
- LOCK.synchronize { CACHE_STORE[filename] = CacheObject.new( data, mtime ) }
56
- data
57
- end
58
-
59
- # Get data from the cache. will throw an exception if there is no data in the cache.
60
- def get_cached filename
61
- CACHE_STORE[filename].data # if CACHE_STORE[filename]
62
- end
63
-
64
- # Remove data from the cache, if it exists.
65
- def clear_cached filename
66
- LOCK.synchronize { CACHE_STORE.delete filename } # if CACHE_STORE[filename]
67
- end
68
-
69
- # clears all cached data.
70
- def clear_cache! filename
71
- LOCK.synchronize { CACHE_STORE.clear } # if CACHE_STORE[filename]
72
- end
73
-
74
- # returns true if the filename is cached.
75
- def cached? filename
76
- !CACHE_STORE[filename].nil?
77
- end
78
-
79
- # returns true if the file exists on disk or in the cache.
80
- def file_exists? filename
81
- (CACHE_STORE[filename] || File.exists?(filename)) ? true : false
82
- end
83
-
84
- # returns true if the file has been update since data was last cached.
85
- def cache_needs_update? filename
86
- return true if CACHE_STORE[filename].nil? || CACHE_STORE[filename].mtime < File.mtime(filename)
87
- false
88
- end
89
- end
@@ -1,33 +0,0 @@
1
-
2
- module Plezi
3
-
4
- module_function
5
-
6
- # DANGER ZONE - Plezi Engine. the connections store
7
- IO_CONNECTION_DIC = {}
8
- # DANGER ZONE - Plezi Engine. the connections mutex
9
- C_LOCKER = Mutex.new
10
-
11
- # Plezi Engine, DO NOT CALL. disconnectes all active connections
12
- def stop_connections
13
- log 'Stopping connections'
14
- C_LOCKER.synchronize {IO_CONNECTION_DIC.values.each {|c| c.timeout = -1; callback c, :on_disconnect unless c.disconnected?} ; IO_CONNECTION_DIC.clear}
15
- end
16
-
17
- # Plezi Engine, DO NOT CALL. adds a new connection to the connection stack
18
- def add_connection io, params
19
- connection = params[:service_type].new(io, params)
20
- C_LOCKER.synchronize {IO_CONNECTION_DIC[connection.socket] = connection} if connection
21
- callback(connection, :on_message)
22
- end
23
- # Plezi Engine, DO NOT CALL. removes a connection from the connection stack
24
- def remove_connection connection
25
- C_LOCKER.synchronize { IO_CONNECTION_DIC.delete connection.socket }
26
- end
27
-
28
- # clears closed connections from the stack
29
- def clear_connections
30
- C_LOCKER.synchronize { IO_CONNECTION_DIC.values.each {|c| callback c, :on_disconnect if c.disconnected? || c.timedout? } }
31
- end
32
-
33
- end
@@ -1,77 +0,0 @@
1
-
2
- module Plezi
3
-
4
- module_function
5
-
6
- # Plezi event cycle settings: gets how many worker threads Plezi will run.
7
- def max_threads
8
- @max_threads ||= 16
9
- end
10
- # Plezi event cycle settings: sets how many worker threads Plezi will run.
11
- def max_threads= value
12
- raise "Plezi will hang and do nothing if there isn't at least one (1) working thread. Cannot set Plezi.max_threads = #{value}" if value.to_i <= 0
13
- @max_threads = value.to_i
14
- end
15
-
16
- # Plezi Engine, DO NOT CALL. creates the thread pool and starts cycling through the events.
17
- def start_services
18
- # prepare threads
19
- exit_flag = false
20
- threads = []
21
- run_every(5 , Plezi.method(:clear_connections)) #{info "Cleared inactive Connections"}
22
- run_every 3600 , GC.method(:start)
23
- # run_every( 1 , Proc.new() { Plezi.info "#{IO_CONNECTION_DIC.length} active connections ( #{ IO_CONNECTION_DIC.select{|k,v| v.protocol.is_a?(WSProtocol)} .length } websockets)." })
24
- # run_every 10 , -> {Plezi.info "Cache report: #{CACHE_STORE.length} objects cached." }
25
- (max_threads).times { Thread.new { thread_cycle until exit_flag } }
26
-
27
- # Thread.new { check_connections until SERVICES.empty? }
28
- #...
29
- # set signal tarps
30
- trap('INT'){ exit_flag = true; raise "close Plezi" }
31
- trap('TERM'){ exit_flag = true; raise "close Plezi" }
32
- puts "Services running Plezi version #{Plezi::VERSION}. Press ^C to stop"
33
- puts %q{**deprecation notice**:
34
-
35
- v.0.8.0 will consist of many changes that will also influence the API. The 0.8.0 version will mark the begining of some major rewrites, so that the code will be even easier to maintain.
36
-
37
- If your code depends on Timers and other advanced API, please review your code before updating to the 0.8.0 version.
38
-
39
- }
40
- # sleep until trap raises exception (cycling might cause the main thread to ignor signals and lose attention)
41
- (sleep unless SERVICES.empty?) rescue true
42
- # start shutdown.
43
- exit_flag = true
44
- # set new tarps
45
- trap('INT'){ puts 'Forced exit.'; Kernel.exit }#rescue true}
46
- trap('TERM'){ puts 'Forced exit.'; Kernel.exit }#rescue true }
47
- puts 'Started shutdown process. Press ^C to force quit.'
48
- # shut down listening sockets
49
- stop_services
50
- # disconnect active connections
51
- stop_connections
52
- # cycle down threads
53
- info "Waiting for workers to cycle down"
54
- threads.each {|t| t.join if t.alive?}
55
-
56
- # rundown any active events
57
- thread_cycle
58
-
59
- # call shutdown callbacks
60
- SHUTDOWN_CALLBACKS.each {|s| s[0].call(*s[1]) }
61
- SHUTDOWN_CALLBACKS.clear
62
-
63
- # return exit code?
64
- 0
65
- end
66
-
67
- # Plezi Engine, DO NOT CALL. runs one thread cycle
68
- def self.thread_cycle flag = 0
69
- io_reactor rescue false # stop_connections
70
- true while fire_event
71
- fire_timers
72
-
73
- # rescue Exception => e
74
- # error e
75
- # # raise if e.is_a?(SignalException) || e.is_a?(SystemExit)
76
- end
77
- end
@@ -1,93 +0,0 @@
1
-
2
- module Plezi
3
-
4
- module_function
5
-
6
- #######################
7
- ## Events (Callbacks) / Multi-tasking Platform
8
-
9
- # DANGER ZONE - Plezi Engine. an Array containing all the shutdown callbacks that need to be called.
10
- SHUTDOWN_CALLBACKS = []
11
- # DANGER ZONE - Plezi Engine. an Array containing all the current events.
12
- EVENTS = []
13
- # DANGER ZONE - Plezi Engine. the Mutex locker for the event machine.
14
- LOCKER = Mutex.new
15
-
16
- # returns true if there are any unhandled events
17
- def events?
18
- LOCKER.synchronize {!EVENTS.empty?}
19
- end
20
-
21
- # Public API. pushes an event to the event's stack
22
- #
23
- # accepts:
24
- # handler:: an object that answers to `call`, usually a Proc or a method.
25
- # *arg:: any arguments that will be passed to the handler's `call` method.
26
- #
27
- # if a block is passed along, it will be used as a callback: the block will be called with the values returned by the handler's `call` method.
28
- def push_event handler, *args, &block
29
- if block
30
- LOCKER.synchronize {EVENTS << [(Proc.new {|a| Plezi.push_event block, handler.call(*a)} ), args]}
31
- else
32
- LOCKER.synchronize {EVENTS << [handler, args]}
33
- end
34
- end
35
-
36
- # Public API. Runs the block asynchronously by pushin it as an event to the event's stack
37
- #
38
- # accepts a block to be executed asynchronously.
39
- #
40
- def run_async *args, &block
41
- LOCKER.synchronize {EVENTS << [ block, args ]} if block
42
- block
43
- end
44
-
45
- # Public API. creates an asynchronous call to a method, with an optional callback:
46
- # demo use:
47
- # `callback( Kernel, :sleep, 1 ) { puts "this is a demo" }`
48
- # callback sets an asynchronous method call with a callback.
49
- #
50
- # parameters:
51
- # object:: the object holding the method to be called (use `Kernel` for global methods).
52
- # method:: the method's name (Symbol). this is the method that will be called.
53
- # *arguments:: any additional arguments that should be sent to the method (the main method, not the callback).
54
- #
55
- # this method also accepts an optional block (the callback) that will be called once the main method has completed.
56
- # the block will recieve the method's returned value.
57
- #
58
- # i.e.
59
- # puts 'while we wait for my work to complete, can you tell me your name?'
60
- # Plezi.callback(STDIO, :gets) do |name|
61
- # puts "thank you, #{name}. I'm working on your request as we speak."
62
- # end
63
- # # do more work without waiting for the chat to start nor complete.
64
- def callback object, method, *args, &block
65
- push_event object.method(method), *args, &block
66
- end
67
-
68
- # Public API. adds a callback to be called once the services were shut down. see: callback for more info.
69
- def on_shutdown object=nil, method=nil, *args, &block
70
- if block && !object && !method
71
- LOCKER.synchronize {SHUTDOWN_CALLBACKS << [block, args]}
72
- elsif block
73
- LOCKER.synchronize {SHUTDOWN_CALLBACKS << [(Proc.new {|*a| block.call(object.method(method).call(*a))} ), args]}
74
- elsif object && method
75
- LOCKER.synchronize {SHUTDOWN_CALLBACKS << [object.method(method), args]}
76
- end
77
- end
78
-
79
- # Plezi Engine, DO NOT CALL. pulls an event from the event's stack and processes it.
80
- def fire_event
81
- event = LOCKER.synchronize {EVENTS.shift}
82
- return false unless event
83
- begin
84
- event[0].call(*event[1])
85
- rescue OpenSSL::SSL::SSLError => e
86
- warn "SSL Bump - SSL Certificate refused?"
87
- rescue Exception => e
88
- raise if e.is_a?(SignalException) || e.is_a?(SystemExit)
89
- error e
90
- end
91
- true
92
- end
93
- end