Class: RestCore::Promise
- Inherits:
-
Object
- Object
- RestCore::Promise
- Includes:
- RestCore
- Defined in:
- lib/rest-core/promise.rb
Defined Under Namespace
Classes: Future
Constant Summary
Constants included from RestCore
ASYNC, CLIENT, DRY, FAIL, HIJACK, LOG, PROMISE, REQUEST_HEADERS, REQUEST_METHOD, REQUEST_PATH, REQUEST_PAYLOAD, REQUEST_QUERY, REQUEST_URI, RESPONSE_BODY, RESPONSE_HEADERS, RESPONSE_KEY, RESPONSE_SOCKET, RESPONSE_STATUS, Simple, TIMER, Universal, VERSION
Class Method Summary collapse
Instance Method Summary collapse
-
#defer(&job) ⇒ Object
called in client thread.
-
#done? ⇒ Boolean
It’s considered done only if the HTTP request is done, and we’re not in asynchronous mode otherwise the callback should be called first.
-
#fulfill(body, status, headers, socket = nil) ⇒ Object
called in requesting thread after the request is done.
- #future_body ⇒ Object
- #future_failures ⇒ Object
- #future_headers ⇒ Object
- #future_response ⇒ Object
- #future_socket ⇒ Object
- #future_status ⇒ Object
-
#initialize(env, k = RC.id, immediate = false, &job) ⇒ Promise
constructor
A new instance of Promise.
- #inspect ⇒ Object
-
#reject(error) ⇒ Object
called in requesting thread if something goes wrong or timed out.
-
#then(&action) ⇒ Object
append your actions, which would be called when we’re calling back.
-
#wait ⇒ Object
called in client thread (client.wait).
-
#yield ⇒ Object
called in client thread (from the future (e.g. body)).
Methods included from RestCore
Constructor Details
#initialize(env, k = RC.id, immediate = false, &job) ⇒ Promise
Returns a new instance of Promise.
24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rest-core/promise.rb', line 24 def initialize env, k=RC.id, immediate=false, &job self.env = env self.k = [k] self.immediate = immediate self.body, self.status, self.headers, self.socket, self.response, self.error, self.called = nil self.condv = ConditionVariable.new self.mutex = Mutex.new defer(&job) if job end |
Class Method Details
.claim(env, k = RC.id, body, status, headers) ⇒ Object
18 19 20 21 22 |
# File 'lib/rest-core/promise.rb', line 18 def self.claim env, k=RC.id, body, status, headers promise = new(env, k) promise.fulfill(body, status, headers) promise end |
Instance Method Details
#defer(&job) ⇒ Object
called in client thread
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rest-core/promise.rb', line 57 def defer &job if pool_size < 0 # negative number for blocking call job.call elsif pool_size > 0 self.task = client_class.thread_pool.defer do synchronized_yield{ job.call } end else Thread.new{ synchronized_yield{ job.call } } end env[TIMER].on_timeout{ reject(env[TIMER].error) } if env[TIMER] end |
#done? ⇒ Boolean
It’s considered done only if the HTTP request is done, and we’re not in asynchronous mode otherwise the callback should be called first. For synchronous mode, since we’re waiting for the callback anyway, we don’t really have to check if it’s called.
114 115 116 |
# File 'lib/rest-core/promise.rb', line 114 def done? !!status && !(immediate && !called) end |
#fulfill(body, status, headers, socket = nil) ⇒ Object
called in requesting thread after the request is done
83 84 85 86 87 88 89 90 |
# File 'lib/rest-core/promise.rb', line 83 def fulfill body, status, headers, socket=nil env[TIMER].cancel if env[TIMER] self.body, self.status, self.headers, self.socket = body, status, headers, socket # under ASYNC callback, should call immediately callback_in_async if immediate condv.broadcast # client or response might be waiting end |
#future_body ⇒ Object
42 |
# File 'lib/rest-core/promise.rb', line 42 def future_body ; Future.new(self, RESPONSE_BODY ); end |
#future_failures ⇒ Object
46 |
# File 'lib/rest-core/promise.rb', line 46 def future_failures; Future.new(self, FAIL) ; end |
#future_headers ⇒ Object
44 |
# File 'lib/rest-core/promise.rb', line 44 def future_headers ; Future.new(self, RESPONSE_HEADERS); end |
#future_response ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/rest-core/promise.rb', line 47 def future_response env.merge(RESPONSE_BODY => future_body, RESPONSE_STATUS => future_status, RESPONSE_HEADERS => future_headers, RESPONSE_SOCKET => future_socket, FAIL => future_failures, PROMISE => self) end |
#future_socket ⇒ Object
45 |
# File 'lib/rest-core/promise.rb', line 45 def future_socket ; Future.new(self, RESPONSE_SOCKET ); end |
#future_status ⇒ Object
43 |
# File 'lib/rest-core/promise.rb', line 43 def future_status ; Future.new(self, RESPONSE_STATUS ); end |
#inspect ⇒ Object
38 39 40 |
# File 'lib/rest-core/promise.rb', line 38 def inspect "<#{self.class.name} for #{env[REQUEST_URI]}>" end |
#reject(error) ⇒ Object
called in requesting thread if something goes wrong or timed out
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rest-core/promise.rb', line 93 def reject error task.cancel if task self.error = if error.kind_of?(Exception) error else Error.new(error || 'unknown') end fulfill('', 0, {}) end |
#then(&action) ⇒ Object
append your actions, which would be called when we’re calling back
105 106 107 108 |
# File 'lib/rest-core/promise.rb', line 105 def then &action k << action self end |
#wait ⇒ Object
called in client thread (client.wait)
71 72 73 74 |
# File 'lib/rest-core/promise.rb', line 71 def wait # it might be awaken by some other futures! mutex.synchronize{ condv.wait(mutex) until done? } unless done? end |
#yield ⇒ Object
called in client thread (from the future (e.g. body))
77 78 79 80 |
# File 'lib/rest-core/promise.rb', line 77 def yield wait callback end |