Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream delegate context tracing #996

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

pwetrifork
Copy link
Contributor

This pull request implements XMPPStream element event tracing as described in the "XMPPStream element events" section in #993.

From stream interface point of view, this feature is purely additive and therefore transparent to the existing API consumers.

This pull request does not add any new unit tests as there is no direct test coverage of XMPPStream-related logic.

@chrisballinger
Copy link
Collaborator

This PR has some deep changes that I'd like to investigate/understand further before merging. I'll make some comments inline.

Copy link
Collaborator

@chrisballinger chrisballinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some thoughts so far

@@ -644,6 +646,7 @@ extern const NSTimeInterval XMPPStreamTimeoutNone;
* Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
**/
- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr;
- (void)sendElement:(NSXMLElement *)element registeringEventWithID:(NSString *)eventID andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding new parameter should match the existing order like:

- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt * _Nullable * _Nullable)receiptPtr registeringEventWithID:(NSString *)eventID;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

* This method returns nil if called outside of those callbacks.
* For more details, please refer to @c XMPPElementEvent documentation.
*/
- (nullable XMPPElementEvent *)currentElementEvent;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer property style getter:

@property (nonatomic, readonly, nullable) XMPPElementEvent * currentElementEvent;

However, I'm not sure this is necessarily the right way to relay the information if it only works within certain callbacks. What about adding an additional (optional) elementEvent parameter to didSendXXX/didFailToSendXXX/didReceiveXXX callbacks? Modules that want to be aware of this information could opt-in to the new callback signatures, but existing modules could keep using the old callbacks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property syntax fixed, see my comment regarding the design

* @see beginDelayedProcessing
* @see endDelayedProcessingWithToken
*/
@property (nonatomic, assign, readonly, getter=isProcessingCompleted) BOOL processingCompleted;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match Apple's newer style conventions for Swift, I'd prefer not using a renamed getter and simply naming the property isProcessingCompleted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

*
* Using @c XMPPElementEvent handles is a more robust approach than relying on pointer equality of @c XMPPElement instances.
*/
@interface XMPPElementEvent : NSObject
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps move this interface to a separate file XMPPElementEvent.h because this header is already huge

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -1032,6 +1124,9 @@ extern const NSTimeInterval XMPPStreamTimeoutNone;
* These methods are called after their respective XML elements are sent over the stream.
* These methods may be used to listen for certain events (such as an unavailable presence having been sent),
* or for general logging purposes. (E.g. a central history logging mechanism).
*
* Delegates can obtain event metadata associated with the respective element by calling @c currentElementEvent on @c sender
* from within these callbacks. For more details, please refer to @c XMPPElementEvent documentation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an extension to my comment above about adding XMPPElementEvent to the callbacks. Could you create another delegate protocol to complement XMPPStreamDelegate and put it in another file? For instance:

@protocol XMPPElementEventDelegate <NSObject>
 - (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq elementEvent:(XMPPElementEvent*)elementEvent;
 - (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message elementEvent:(XMPPElementEvent*)elementEvent;
// etc..
 - (void)xmppStream:(XMPPStream *)sender didFinishProcessingElementEvent:(XMPPElementEvent *)event NS_SWIFT_NAME(xmppStream(_:didFinishProcessing:));
@end

* Steps 2. and 4. are only required if @c becomeCurrentOnQueue:forActionWithBlock: itself is invoked asynchronously
* (e.g. in a network or disk IO completion callback).
*/
@interface GCDMulticastDelegateInvocationContext : NSObject
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see why this is needed for the current approach but it feels complex and looks like it requires enforcing a certain style to future XMPPStream changes. For instance now instead of calling multicastDelegate directly, you have to be sure to call performDelegateActionWithElementEvent, and if you don't... what happens?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment below.

@pwetrifork
Copy link
Contributor Author

Being pressed against time I'm a bit slow to respond; I will take a look at your feedback asap.

@pwetrifork
Copy link
Contributor Author

Regarding currentElementEvent property vs additional delegate callbacks:

Having the additional callback variants was actually our initial approach, but we felt it introduced even more clutter. First, it added quite a few methods to the already busy stream interface. Then, instead of ensuring to call performDelegateActionWithElementEvent within the stream implementation, one had to ensure to invoke both old and new callbacks. Finally, event parameters spilled to module delegate callbacks.

The main feat of the property approach is how transparent it is w.r.t. module logic. Note that in a standard propagation scenario, a module's delegate can reach to the stream's current event within a callback and all of this happens with no involvement on module's part. This means it works for all existing modules; I have not researched if there are any scenarios for current modules where this could be useful though.

@chrisballinger
Copy link
Collaborator

Thanks for that! I wanted to get @robbiehanson to take a quick look, but I think if it otherwise doesn't cause regressions for existing code it is good to merge.

Squashed commits:
[73bf7ae] Rename XMPPElementEvent processingCompleted property
[d1bbfce] Move XMPPElementEvent interface declaration to a separate header file
[b7ac0a7] Use property syntax for XMPPStream currentElementEvent
[ba381c4] Reorder XMPPStream sendElement method parameters
@pwetrifork pwetrifork force-pushed the stream-delegate-context-tracing branch from 0c38e01 to 613183a Compare November 29, 2017 07:06
@pwetrifork
Copy link
Contributor Author

Rebased to resolve project file conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants