Thanks for catching this! I simply didn't think of the case where a JVM sends more than 2^31 messages without JVM restart. If you do, I'd love to talk to you =).
More seriously, Apple doesn't interpret the passed identifier at all, as it is application-specific used mainly for book-keeping purposes and Apple has no restrictions on it. Internally, the library uses a signed-integer because it's convenient. It is wise for the identifiers maintain a sense of uniqueness and have some correlation with time.
There are more appropriate representation IMHO, like packed-values to represent the sending ApnsService, as currently messages sent using multiple ApnsService instances get the same identifiers.
The library doesn't specify how it generates its identifiers, so it is implementation-specific and you shouldn't even depend on the identifier being a counter. When the time comes and there is a need to have a clear contract, then I'll revisit how identifier is generated and document it.
Regards,- Mahmood
On Wednesday, July 20, 2011 at 9:02 AM, amitfrid wrote:
> you right. I wonder if Apple doesn't treat it as signed, and I think
> that I got my answer :)
>
> Thanks,
> Amit
>
> On Jul 20, 3:11 pm, Olivier Costet <Olivier.Cos...@zenprise.com (http://zenprise.com)>
> wrote:
> > 0x7fffffff plus one is always 0x80000000, yes. But 0x80000000 is only
> > negative if you _treat it_ as a signed, 32-bit integer. If you treat it
> > as an unsigned integer, it's positive.
> >
> > OC.
> >
> >
> >
> >
> >
> >
> >
> > On Wed, 2011-07-20 at 04:42 -0700, amitfrid wrote:
> > > Java Does not support signed Integers, so the integer max value + 1
> > > will get you to overflow, resulting in integer min value which is a
> > > negative number.
> > > I guess that if apple supports negative numbers (why shouldn't
> > > them...) it's adequate.
> >
> > > Thanks,
> > > Amit
> >
> > > On Jul 20, 2:37 pm, Olivier Costet <Olivier.Cos...@zenprise.com (http://zenprise.com)>
> AFAIK, when Apple returns an error code for a message, it attached the
> identifier id, so it has a meaning. I've took it from here:
> http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW4
Again, I emphasize my words: "Apple doesn't interpret the passed identifier at all," it is application specific. Apple simply return the identifier for the failed message whatever it is. It is your application that assigns the meaning to the identifier, not Apple.
The Apple documentation specifies: "An arbitrary value that identifies this notification. This same identifier is returned in a error-response packet if APNs cannot interpret a notification." *Arbitrary* being the operating word here.
Regards,
Mahmood
> So the identifier has some meaning on the application side. Would it
> be possible to enhance the uniqueness of the identifier in the future?
It is possible, but it's not obvious to me how it should be done yet,
and we haven't had the need to address it yet. The library aims to
have the identifiers unique at the ApnsService instance level, but
it's not guaranteed.
For now, constructing EnhancedApnsNotification gives you more control
on how the identifiers should constructed.
- Mahmood
> Just for the example, by using a static short member of the
> APNSService which will uniquely assign the high byte in the 4-byte
> identifier (so it support 255 uniquely instances) where the rest 3
> bytes are assigned by the current counter or other mechanism which is
> unique per instance only.
Correct. That's what I meant by a packed value in my earlier email.
For a pointer of some possibilities, checkout the follow blog article
and search for the keywords included:
http://engineering.twitter.com/2010/06/announcing-snowflake.html .
However, you need to decide what properties you want the counters to
do: does it need to be globally unique? Is it going to be persisted?
Should it be sortable? Should be timed-based? Should the retry to be
local (in the same process as the instance) or across processes (the
retry process will need to identify the message uniquely).
In my current design, I implemented just enough work to get the retry
work to work smoothly, and later library versions will make that even
easier. For now, you can create an ApnsDelegate for each ApnsService
that keep a cache of the messages, and then whenever a message fails
(and `connectionClosed()` is called) the failed message can be
identified. I haven't seen the need for using a globally unique
identifier or packed values yet
- Mahmood