Code Monkey home page Code Monkey logo

Comments (18)

argon avatar argon commented on June 12, 2024

No, that is not how the Apple service is designed. Nor does it really make sense to require a success callback.

There are 2 stages happening here, the first is that the message is successfully sent to the server.

Second if there is any sort of problem with the message you will receive an error, if not then there is no step 2. There is no notification that a message has been successfully sent to the device as that would cause a massive amount of unnecessary bandwidth usage for high volume applications.

The push system is a lot more like UDP than TCP, as such it is very much "fire and forget" and it seems like you might want to rethink how your system works. What exactly is it you're trying to accomplish with a successCallback?

from node-apn.

bosky101 avatar bosky101 commented on June 12, 2024

thanks argon. i just wanted to have a consistent usage with how other library usually pass callback(er, result).

i have implemented notification specific errorCallback for node-apn here. but cancelled the pull-request when i realised that successcallback wasnt working.
explanation here bosky101@90e4d7e
code here bosky101@d88e23c

~B

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

While it's not feasible to have a callback fire upon successful delivery of a notification to a device, it would be nice to be able to have a callback called upon successful communication with the Apple service (and acceptance by Apple of the payload). This way I can know when its safe to exit the process that's sending the notifications to Apple. I'm going to try forking and submit a pull request if I can figure it out. But do you agree there's some value in providing a hook to client code for when the communication with Apple is complete?

from node-apn.

argon avatar argon commented on June 12, 2024

Why are you getting the process sending notifications to Apple to exit? Are you sending notifications in batches?
Something which might work is if there is a method to tell the module that you are done sending notifications so when the module has finished sending it will automatically close the connection, and when that happens, if no other events are running then the process will exit.

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

I am in fact sending notifications in batches, using the library to process notifications queued up to go out worldwide at scheduled intervals. I'd like to have that process clean up after itself and exit with a success/failure code once its done with its work. I also have a test harness where I trigger the process from a web page in my test environment and would like to respond to that request in a timely fashion.

I'm still a little new to nodeJS, so I'm not entirely clear on what you mean by "a method to tell the module that you are done sending notifications", unless you mean adding a method to the library so I can indicate to it that I'm done submitting a batch of notifications (perhaps useful for implementation of a completion callback for the entirety of a batch?)

Regarding what I was considering a useful addition to your library, I'm thinking successCallback may be a misleading name for the hook I'm interested in, but acceptanceCallback might suggest appropriately to the module user that it's only making a claim on whether the communication with Apple is complete.

Make sense or am I way off base here?

from node-apn.

argon avatar argon commented on June 12, 2024

node.js is event driven meaning there isn't a loop, so the process will stay alive all the time there's work to do. In this case while there is an active connection to apple the process wont exit. What you're trying to accomplish isn't best solved by receiving a "sent" callback for each and every notification. Particularly when a subsequent "error" callback may occur. Also you're not interested whether individual messages are actually sent, it's more work for you to keep track of which have and haven't been sent, you just want to know when they're all done. If you were to call a function to tell the module that you don't want to send any more messages, then once the module has finished sending them all it could close the connection and raise an event to inform you of the disconnection. In the case there there are no other open connections or outstanding timers then the process will exit, or you could receive the disconnect event and send a message back to your control systems.

How does that sound?

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

Sadly, I actually do have an interest in knowing which ones made it to Apple, as I maintain in my database a flag indicating whether or not the notification was presented to Apple and also where I record when the presentation occurred. This is useful to me in that if something happens to my server I can easily identify which notifications still need to be sent as opposed to which are simply queued waiting for the appropriate time to send. This way it is also not hard for me to write my process so that it may resume where it left off should the batch process go down for whatever reason. If my client's business succeeds as we hope it will, I may also want to have multiple processes burning through my batches of queued notifications. Tracking success/fail of individual submissions will make this multi-process scenario easier to manage should unexpected (network or otherwise) failures occur during processing.

Aside from recording submission status, anecdotally, I've had some problems when I was simply waiting for nodeJS to shut itself down. Submission of a single push notification resulted in a process that lingered around for upwards of 5 minutes without any other activity. I'd like to avoid that, but perhaps I'm doing something else wrong there though?

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

I was, however, unaware of the possibility of the errorCallback occuring after the initial communication with Apple is complete. Perhaps I need to inspect your source to understand better just what is happening there, or am just misunderstanding the scenario you mention.

Regardless, thanks for the great library and your attention regarding this issue!

from node-apn.

argon avatar argon commented on June 12, 2024

Well as I said, at present the connection will be maintained indefinitely so the process wont quite by itself. If I were to add a method to tell the process you don't want to send any more then it can close the connection and the process would quit. I'm thinking about having an overhaul of the module in light of some recent comments I've heard and you've given me food for thought. I will be creating a new API (backwards compatible I hope) which will allow event listeners to be attached to the module and there will be a "notification sent" and "connectionClosing" event to attach to. I will probably work on this tomorrow.

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

Fantastic! And thanks so much!

I did miss that mention of the indefinite connection. I get it now.

from node-apn.

argon avatar argon commented on June 12, 2024

I just noticed there is a "connectionTimeout" parameter on the module which I don't expose through the options object which could ensure the connection closes. But it's not very smart at the moment and it'll just destroy the connection a given amount of time after its established regardless of whether there are still notifications to send. Can't remember how that got in there but it does need fixing.

from node-apn.

argon avatar argon commented on June 12, 2024

If you want to take a look at the latest "develop" branch you will find the changes I made this morning. I wrote a lengthy commit message in 421c7fd explaining the new features. If you wouldn't mind giving it a go I'd love to get your feedback on functionality.

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

What a fast response, thank you much! I'll definitely check it out. Probably Friday though, as I'm in the US and today will largely be devoted to our Thanksgiving holiday.

Cheers

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

I must admit, after taking a quick look at your new code, I realize I'd made a flawed assumption about the APNs, and had figured that it at least would provide an ACK in response upon receipt of what it recognizes as a valid payload. Considering the volume they're designing for, I guess I'm not too surprised in retrospect, but a few bytes back would have been nice on success. Oh well.

Nevertheless thank you for the new events. I'm currently working on integrating them into my application, and I like how they give me more options despite the limitations inherent in the APNs. I'm thinking instead of trying to record in my database something saying whether Apple "accepted" a notification, I'll switch the semantics so that the flag means that we've exercised due diligence in watching for its rejection. The new events definitely help with that.

In detail, I'm thinking I'll record first when the notification went over the socket. This value I can interpret as "possibly accepted for sending by Apple". I'll then use the error event to set a flag in my database which I can interpret as "definitely rejected by Apple". Finally I am thinking that I will use the connection timeout option on the connection together with its timeout event in order to set a flag in my database meaning "probably accepted by Apple". The idea here is that I can arbitrarily adjust that timeout value upwards to calibrate confidence that the notifications in the batch got through Apple's system without rejection. While it appears the APIs (Apple's) will never offer me a solid answer regarding Apple acceptance of a payload, this way I can at least store something that meaningfully can drive my decision as to whether or not to retry submission.

I have a colleague that calls "Fire and Forget" APIs "Fire and Pray" APIs. I guess that's what we're stuck with here. For me, though, at least this last flag would record whether or not I've abandoned a notification to it ultimate fate in Apple system and intermediary networks. "Godspeed, intrepid Push Notification!" so to speak. Thanks again.

from node-apn.

argon avatar argon commented on June 12, 2024

Well, in fairness you know whether Apple accepted a notification if it leaves the operating system buffer (which is when the event is emitted) and you don't receive an error from them. Don't forget, it's TCP, not UDP so the buffer wont successfully drain until Apples servers receive it.

It's not reasonable to deliver an acknowledgement upon delivery because that could take days and then they need to be concerned with finding the right socket to deliver the notification to, and that's assuming the socket is still open, if it's not then they probably need to wait until your server connects again, which introduces all sorts of session state that creates all kinds of distribution and storage problems they don't need.

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

Right. Agreed. I was expecting a positive ACK upon receipt (not delivery) as opposed to the "negative ACK" of no response. I don't usually visit the level of the technology stack where distinctions between TCP and UDP matter- I'm usually up a layer of abstraction where I think more in terms of synchronous vs. async, or request/response vs. request/callback so I'll trust you (rather than research) that a prompt reply of nothing does in fact properly mean success.

(I guess there's a response packet containing nothing then?) How else would I know the packet ever actually got to them - but no matter, again, I'll just trust you on this - I don't expect you to put me through "transport layer boot camp"

from node-apn.

argon avatar argon commented on June 12, 2024

Suffice to say that if a packet isn't ACKed at the transport layer within a decent period of time the operating system will resend the packet. That's why packet loss makes the internet slow rather than bits of webpages just not being present. The hardware layer of the internet is nowhere near as stable as it appears, TCP does its best to make up the shortfalls!

Let me know if you need anything else but I'm going to close this issue now as I think it's been resolved.

from node-apn.

mike-lang avatar mike-lang commented on June 12, 2024

Sounds good. And thanks again. I'll definitely be using the new features you've put in that develop branch. Good luck with further development of the library

from node-apn.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.