-
Notifications
You must be signed in to change notification settings - Fork 407
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
Fixed a race condition while adding and cancelling an observation #169
Fixed a race condition while adding and cancelling an observation #169
Conversation
@@ -64,6 +66,7 @@ | |||
|
|||
private final List<ObservationRegistryListener> listeners = new CopyOnWriteArrayList<>(); | |||
private final Map<KeyToken, Observation> observationsByToken = new ConcurrentHashMap<>(); | |||
private final Lock observationLock = new ReentrantLock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why us a Lock and not a synchronize(this) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notifying Observation listeners is outside the locks. At the end the same can also be achieved using synchronized blocks. Its just a religious thing which one you chose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to use a lock that is private to the class. Otherwise someone else could also synchronize on "this" and we might get a deadlock (more a theoretical and style discussion).
Of course we can also synchronize on a private object and use synchronized blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no good reason to use a lock here, you can use a private monitor. "private Object monitor = new Object();" if you really want to isolate it.
A synchronize on monitor is superior here because you don't have to rely on the try/finally and you are not using the extra feature of Lock missing from synchronize block.
That's no religious/style thing, just better idiomatic java 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I meant with the last sentence. We can use a private monitor.
47fff24
to
7f695ff
Compare
…tially lead to duplicate observes on the same resource of the same client. Signed-off-by: Bala Azhagappan <balasubramanian.azhagappan@bosch-si.com>
@jvermillard as you suggested, I have pushed the updated version with the two changes. |
Manu is modifying this code and your PR will not be so relevant in the new code. But finally this constraint of duplicate observation should not be handled at Leshan level. This is a CoAP constraint so this should be done in californium. |
I agree with you regarding only one observation per resource restriction belonging to californium. The fact that we have an Could you give a heads up what kind of changes are to be expected in the new code? Is it only reimplementing |
The Observe CoAP spec §3.1 say: Currently in californium, there is no limitation about that. An obversation is just identifying by a Token. The spec say that a target resource is identified by all the options §5.10 that are part of the cache key (= all options except size1). But, as we deviate a little from the spec by allowing observation from different endpoint (This is the case where the CoAP server is behind a NAT), Using the Cache-Key is not so relevant... So I'm not so sure pushing this restriction in californium is still a good idea...
Manu will probably push a PR before the end of the week. |
So Manu pushed its code in the observe_context branch which needs this additionnal feature in Californium. Unfortunately, this will not fix the race condition you find here. There is another race condition between observe and registration, but we think we found a miss-conception in Leshan. As observation is strongly linked to the registration, we think that observation should be store in ClientRegistry(RegistrationStore) What do you think ? |
Yes I agree that Observation is strongly linked to a registration.
You mean to say that instead of having a separate ObservationRegistry, just have the RegistrationStore implement the CaliforniumObservationRegistry or even the new LwM2mObservationStore interface introduced in the branch (observe_context) and clear the observations when a de-registration happens? |
I agree. If When it is implemented that way and merged in to master, then this PR will not be relevant any more, if not it would still be good to have this PR. I have a small request. As the refactoring done in |
Something like this but I need to think more about this. |
I'm not sure to understand why it is needed to separate this. I agree that the registry refactoring could have been done in a separate PR, but then the code handling the observe context would have been duplicated. |
Manu changes was integrated in master so the PR si no more relevant. |
This PR fixes a race condition in
CaliforniumObservationRegistryImpl
while invokingaddObservation
andcancelObservation
calls. Due to this race condition it could still be possible to have a duplicate observation for the same resource and client reported in #163Due to change that came in as a bug fix for issue #168 there can be at most only one active observation for a given resource. So the
ObservationRegistry
interface was changed to reflect the same.Signed-off-by: Bala Azhagappan balasubramanian.azhagappan@bosch-si.com