my apologies if my comments, feedback and alternative
branch were not as helpful to you as they have been to me.
After all of this I now have a much better understanding of
the problem domain and what you have in mind regarding
clustering (in particular I wasn't aware of the load balancing
aspect induced by the CoAP server's constant changing of IP
addresses if behind a NAT firewall).
1) My first modification was to change the
internal/advanced API to introduce a new ObservationStore.
The main modification was:
- Before, the exchange lived all along the observe
relation lifetime.
- Now, we recreate an exchange for each notification.
I mean a new Exchange instance is created from data stored
in ObservationStore each time we receive a new
notification and will be completed/removed as soon as the
notification is handled.
This means that the first response for an observe request
will be accessible via the MessageObserver of the original
Request, then next notifications will be available via
NotificationListener.
This also means that now we are able to handle several
notifications transfered with block-wised(block2) at the
same time. (as there is now 1 exchange by notification)
I understood we agreed on this part. If this is not
the case, we should keep focus on this. (I mean
ignore the point 2) )
My alternative approach tried to re-establish the
Exchange being held in memory for the whole timespan during
which notifications might arrive.
After having given this some more thought, I think that
your approach of re-creating an Exchange from the
information in the observation store for every notification
(and discarding it again after processing) is the right way
to go :-)
I have some concerns though regarding throughput:
If we hit the external shared persistence store (e.g.
Redis) for every notification that is received, we will run
at risk of blocking all available threads with waiting for
the result returning from Redis. This might reduce the
throughtput dramatically. We might be able to remedy this
situation by implementing the ObservationStore as a
two-level cache, the first one in memory keeping only the
most recently used observation state and the second level in
Redis which is only queried if we experience a first level
cache miss (we already talked about hat approach). We could
re-use the LeastRecentlyUsedCache that we use in Scandium
for the first level cache and can can combine it with the
"re-sync from Redis when notification's IP address has
changed" strategy that I have introduced in the
"observe_clustering_alt" branch. This way we might be able
to reduce the external second level cache look-ups to a
minimum and serve the majority of incoming notifications
from memory.