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

Send registration event after sending response to device #249

Closed
wants to merge 2 commits into from

Conversation

sbernard31
Copy link
Contributor

This PR was motivated by #247.

It aims to send registration event (register, update, deregister) after we effectively send the LWM2M response to the device. Even if UDP does not guarantee ordered and like it is explain here it is not mandatory to make it works, this could be an improvement most of the time.

It is largely inspired by what I have done here for #16, but trying to keep the LwM2mResponse immutable.

@tomaszszlek
Copy link

I have tested your PR and it works a little bit strange.
I have following code in my registration listener:
`
@OverRide

public void registered(Registration registration) {
    LOG.info("Client should be registered here at this point");
    try {
        Thread.currentThread().sleep(1000 * 30);
    }
    catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    LOG.info("Register listener finished his work");
}

`

I would expect that client will start register, then server receive the response, finally after 30 seconds my listener code will execute but behavior is different.
On client side I see registration request, after that server is not responding client waits for registration.
When 30 seconds have passed then server is responding to client and registration is finished.
Client logs:

...

2017-01-19 14:36:15,701 INFO RegistrationEngine - Trying to register to coap://localhost:5683

...

2017-01-19 14:36:45,814 INFO RegistrationEngine - Registered with location '/rd/YIgPGdm9d7'.

@sbernard31
Copy link
Contributor Author

You're right. I thought that "exchange complete" notification was called after the response was sent, but it seems I was wrong ... : / .

So, if I understand correctly how californium( the JAVA CoAP library we use) works, I can't see any good solution for this problem...

@sophokles73 What did you think about that ? Did you see any solution to sent registration notification after we send the CoAP response ?

@sbernard31 sbernard31 changed the base branch from master to registrationservice_cleanup January 20, 2017 10:14
registrationService.fireUnregistered(deregistration.getRegistration());
}
registrationService.fireRegistred(registration);
Runnable whenSended = new Runnable (){
Copy link
Contributor

Choose a reason for hiding this comment

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

whenSent

@boaks
Copy link

boaks commented Feb 1, 2017

@sbernard31
I think, the solution depends on the wanted QoS :-).
Though californium tries to decouple the CoAP message logic from the "message transfer" (element-connector), there are two possibilities:

  1. when CoAP core hands over the message to the connector (CoapEndpoint.OutboxImpl)
  2. when the connector realy sends the message

So working on californium eclipse-californium/californium#202 I would guess 2 will be the right. So may be we introduce/extend a "callback", which informs us, if the message is send or droped.

@sbernard31
Copy link
Contributor Author

sbernard31 commented Feb 1, 2017

So may be we introduce/extend a "callback", which informs us, if the message is send or droped

I like the idea.

@sophokles73
Copy link
Contributor

Sorry for joining the party this late but I am not sure if I understand the intention fully. Do you guys want to make sure that the event is only fired once we are sure that the LWM2M client has received the server's response to its registration request? If not then IMHO it doesn't really make a difference which stage of Cf processing the response we use as the trigger for firing the event. The most likely reason for the client not receiving the response will be that the message gets lost during transmission. It is pretty unlikely that the message gets lost while flowing through Cf's stack...

@sbernard31
Copy link
Contributor Author

Do you guys want to make sure that the event is only fired once we are sure that the LWM2M client has received the server's response to its registration request?

No, we want to make sure event is only fired once we sent the message.

@sbernard31 sbernard31 changed the base branch from registrationservice_cleanup to master February 2, 2017 15:56
@sophokles73
Copy link
Contributor

Ok, I have taken a close look at your code @sbernard31. The problem is that ExchangeObserver.completed() gets invoked in Matcher.sendResponse() before the CoAP response is actually sent via the connector (by the Outbox). This is because the Matcher is higher in the stack than the Outbox (which is actually at the bottom of the stack).
Why don't you simply remove the ExchangeObserverAdapter and invoke SendableResponse.sent() as the last step from within RegisterResource.handleRegister() right after you have sent back the response to the client?

...
        // Create CoAP Response from LwM2m request
        // -------------------------------
        if (response.getCode() == org.eclipse.leshan.ResponseCode.CREATED) {
            exchange.setLocationPath(RESOURCE_NAME + "/" + response.getRegistrationID());
            exchange.respond(ResponseCode.CREATED);
        } else {
            exchange.respond(fromLwM2mCode(response.getCode()), response.getErrorMessage());
        }
        sendableResponse.sent();
}

@sbernard31
Copy link
Contributor Author

sbernard31 commented Feb 3, 2017

Because, exchange.respond() does not synchronously sent the response.

  • The message will be pushed in a queue of the connector and will be handled later by a thread.
    or
  • The message will be handled asynchronously by the coapendpoint if there is a customExecutor.

(This is not the case here but we can also imagine that the response is sent using block mode and we would like to be notify when the last block is sent)

@sbernard31
Copy link
Contributor Author

In case we have no customExecutor, your proposition is probably better than using ExchangeObserver.completed(), because the event callback is called later.
And in all case event handling will not block message delivery.

I will do that and @tomaszszlek would be able to test it and tell us if it's better.

@sophokles73
Copy link
Contributor

Because, exchange.respond() does not synchronously sent the response.

The message will be pushed in a queue of the connector and will be handled later by a thread.
or
The message will be handled asynchronously by the coapendpoint if there is a customExecutor.

That's true but you cannot rely on the order the UDP packets will be delivered to the client anyway so I do not see why this should be a problem ...

@boaks
Copy link

boaks commented Feb 3, 2017

It is pretty unlikely that the message gets lost while flowing through Cf's stack...

According eclipse-californium/californium#104 messages should be dropped, if they were "sent" into the wrong DTLS session. Though the message process flow seems to be potential asynchron/parallel, the right time point in my opinion would be the one, when the DTLS session used for encryption is known and either matching on not matching (and therefore the message should be dropped).

@sbernard31
Copy link
Contributor Author

That's true but you cannot rely on the order the UDP packets will be delivered to the client anyway so I do not see why this should be a problem ...

I agree but most of the time users want to send request just after registration is done. (using registered event). Like David explained here it works even with disordered message . But most of the time, messages are sent in right order, so this change can avoid the first retransmission.
This is just a potential optimization.

@sbernard31
Copy link
Contributor Author

@tomaszszlek I pushed the solution described by @sophokles73. Does it better for you ?

@sophokles73
Copy link
Contributor

@sbernard31,

any news on this? FMPOV this is an improvement anyway so I would be ok to merge this even without further feedback from @tomaszszlek ...

@sbernard31
Copy link
Contributor Author

Finally, integrated in master (commit ece1c3e)

@sbernard31 sbernard31 closed this Apr 12, 2017
@sbernard31 sbernard31 deleted the event_after_response branch June 22, 2017 13:35
mike-scott pushed a commit to mike-scott/leshan that referenced this pull request Jan 31, 2018
…ipse-leshan#249)

* Provide proper OSGi meta-data for all modules eclipse-leshan#248

Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
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.

6 participants