Closed jsgoecke closed 13 years ago
Not quite. The outgoing Say message is one-way. You send it to the Transport layer and it goes off into the aether. When that Say command starts executing, the Ozone server should send a message back down the Transport layer which gets turned into a brand new Say object. This should be (but probably is not yet) the return value of Transport#write. It is this object that is returned that contains the cmd_id which is necessary for generating the response events such as #pause and #resume. We just have not gotten that far in the testing yet.
Yeah, sorry, was thinking in my synchronous DSLish way. What I mean, is that an event should return that I may read off of the queue and get the object I need to execute the control events on (pause, resume, stop, etc).
What we have now, is #pause!, #resume! methods on Say. These rely on the Say object knowing its command ID, which it does not until we get an IQ result containing a <ref/>
. Fortunately, Ozone::Connection#write
blocks until we get this back, and in this process the command_id is tagged on the Say. Thus, if everything is working correctly, once write returns you should be able to call #pause! on your original Say object.
Of course, there are several failure modes:
Connection#write
will block for. Currently, this results in the string representation of a Timeout::Error being written to the queue, which fails miserably. I suspect what we really want to do here is raise either a TransportError or a ProtocolError (most likely the former) with a message stating that no response was received.In the case of #1 above, we need to add a mechanism to cancel the original command. If XMPP has guaranteed delivery and we do not get a response back in 3 seconds, it's likely the command is queued somewhere. Also: is 3 seconds sufficient?
As for #3, I think that the Say object should track its own state. There are too many backend-specific details that are relevant, which is exactly the kind of thing we want to hide from the frameworks.
XMPP does not include guaranteed delivery in the core spec, though it is the case that an IQ MUST respond immediately. Any command queueing should not cause a delay to an IQ response. As such, if we're following that spec, any delay more than x should be considered as failed delivery of some variety.
I'll look into commands tracking their own state.
Commands now track their own state (they know when they are new, requested, executing, paused, stopped, etc) and their actions (#stop!, #pause!, etc) now execute directly (they do not return a
As for timeouts, see https://github.com/tropo/punchblock/issues/50
Please re-open if I have not covered this fully.
If I understand the scenario correctly, the Message::Say.new 'http://foobar.com', :url should return an object that I may then do something like:
say = @protocol::Message::Say.new 'http://foobar.com', :url say.pause say.resume
The issue is, the Say does not return an object before playback is over so that I may act upon it. Here is the wire and transport log:
https://gist.github.com/d4da52b914cb00d22c9f