Module: EventMachine::IMAP::ContinuationSynchronisation
- Included in:
- CommandSender
- Defined in:
- lib/em-imap/continuation_synchronisation.rb
Overview
The basic IMAP protocol is an unsynchronised exchange of lines, however under some circumstances it is necessary to synchronise so that the server acknowledges each item sent by the client.
For example, this happens during authentication:
C: A0001 AUTHENTICATE LOGIN
S: +
C: USERNAME
S: +
C: PASSWORD
S: A0001 OK authenticated as USERNAME.
And during the sending of literals:
C: A0002 SELECT {8}
S: + continue
C: All Mail
S: A0002 OK
In order to make this work this module allows part of the client to block the outbound link while waiting for the continuation responses that it is expecting.
Instance Method Summary collapse
-
#await_continuations(&block) ⇒ Object
Await further continuation responses from the server, and pass them to the given block.
- #awaiting_continuation? ⇒ Boolean
-
#listen_for_continuation ⇒ Object
Add a single, permanent listener to the connection that forwards continuation responses onto the currently awaiting block.
- #post_init ⇒ Object
-
#when_not_awaiting_continuation(&block) ⇒ Object
If nothing is listening for continuations from the server, execute the block immediately.
Instance Method Details
#await_continuations(&block) ⇒ Object
Await further continuation responses from the server, and pass them to the given block.
As a side-effect causes when_not_awaiting_continuations to queue further blocks instead of executing them immediately.
NOTE: If there’s currently a different block awaiting continuation responses, this block will be added to its queue.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/em-imap/continuation_synchronisation.rb', line 47 def await_continuations(&block) Listener.new(&block).tap do |waiter| when_not_awaiting_continuation do @awaiting_continuation = waiter.stopback do @awaiting_continuation = nil waiter.succeed end end end end |
#awaiting_continuation? ⇒ Boolean
35 36 37 |
# File 'lib/em-imap/continuation_synchronisation.rb', line 35 def awaiting_continuation? !!@awaiting_continuation end |
#listen_for_continuation ⇒ Object
Add a single, permanent listener to the connection that forwards continuation responses onto the currently awaiting block.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/em-imap/continuation_synchronisation.rb', line 60 def listen_for_continuation add_response_handler do |response| if response.is_a?(Net::IMAP::ContinuationRequest) if awaiting_continuation? @awaiting_continuation.receive_event response else fail Net::IMAP::ResponseError.new("Unexpected continuation response from server") end end end end |
#post_init ⇒ Object
29 30 31 32 33 |
# File 'lib/em-imap/continuation_synchronisation.rb', line 29 def post_init super @awaiting_continuation = nil listen_for_continuation end |
#when_not_awaiting_continuation(&block) ⇒ Object
If nothing is listening for continuations from the server, execute the block immediately.
Otherwise add the block to the queue.
When we have replied to the server’s continuation response, the queue will be emptied in-order.
80 81 82 83 84 85 86 |
# File 'lib/em-imap/continuation_synchronisation.rb', line 80 def when_not_awaiting_continuation(&block) if awaiting_continuation? @awaiting_continuation.bothback{ when_not_awaiting_continuation(&block) } else yield end end |