-
Notifications
You must be signed in to change notification settings - Fork 14
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
Proposal: rework top-level API #76
Conversation
6ae9d77
to
97436c7
Compare
817d5e3
to
cc5cf64
Compare
5f14dc5
to
e7593a2
Compare
e7593a2
to
4a44d63
Compare
Ok! Ready for review @shamblett, @JKRhb! Linting, formatting & tests are passing, examples are working :) Not sure how to go about reviewing what turned out to be a gargantuan PR, sorry for that. Perhaps the best is to just start with viewing and running the examples to get a feel for the API. Everything is tested except for multicast, didn't have a good way of testing it. |
53c2729
to
d746798
Compare
Thank you for your hard work, @JosefWN!
Maybe aspects like the test server and flutter example removal could be spun off into its own PR? That would reduce the size of the PR a bit |
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 both the CoapMessage
and the CoapRequest
constructors could be simplified a bit. (This requires some more changes at other places in the code base.)
8dc6fb3
to
80c7b4d
Compare
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.
LGTM :) @shamblett Can you also have a look on this PR? :)
beeed5c
to
331637d
Compare
lib/src/coap_option.dart
Outdated
int get hashCode { | ||
const prime = 31; | ||
var result = 1; | ||
return result = prime * result + _type; | ||
return prime + _type; | ||
} |
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.
Oh, one last thing: I think we could also use Object.hash()
in places like this one (here it would probably be simply return Object.hash(_type)
).
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.
Ah, nice catch. In addition, if all fields are included in Object.hash()
, I don't think we need to override hashCode
or operator ==
?
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.
Okay, I found a couple more places to clean up while I was at it: fcc5f66
With client mapping 1:1 to a socket we don't need CoapKeyUri
, we can match blockwise requests on token. Having a List<Map<int?, CoapExchange>>
for matching on id and a Map<String, CoapExchange>
for matching on token works just fine. There is no need for the other two wrapping classes.
I first noticed the CoapObserveNotificationOrderer
had an odd getNextObserveNumber
method, then I realized the entire class was not used at all. Removed it for now, confusing with dead code.
Re-ran all examples and everything works.
lib/src/net/coap_exchange.dart
Outdated
@@ -219,7 +227,7 @@ class CoapKeyToken { | |||
class CoapKeyUri { | |||
/// Construction | |||
CoapKeyUri(this._uri, this._endpoint) { | |||
_hash = _uri.hashCode * 31 + (_endpoint == null ? 0 : _endpoint.hashCode); | |||
_hash = _uri.hashCode * 31 + (_endpoint?.hashCode ?? 0); |
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 guess here we could use something like this?
_hash = _uri.hashCode * 31 + (_endpoint?.hashCode ?? 0); | |
_hash = Object.hash(_uri, _endpoint); |
1115c3e
to
950ecb4
Compare
950ecb4
to
fcc5f66
Compare
I've merged this to its own branch for now, issue75, while I check it out. One question about logging, the original logging was really supplied so users could just turn on logging and supply me with a log of what happened when they raised an issue, without this we are pretty blind. The old logging although as you say problematic in itself did allow post mortem debugging for issue investigation. Are we now saying we are just replacing the old logging with print statements? This is OK but we mustn't lose detail here, the examples now provide minimal logging(OK these of course work so that maybe why). Will we still be able to see message detail, i.e token's/sequence numbers/flags/block counts etc. that we used to do? Sorry if I've missed something here. |
Hi @shamblett, and sorry for the large PR! Personally I'm a big fan of the event bus since it helps us not only decouple the components within the library, but also gives us the opportunity to introspect the request/response flow. In this PR I always fire events (even if there is a hook) for this purpose. I'm also always including data with all events, so we can differentiate between multiple concurrent requests. To make debug logging easier, we could expose the bus on the client as well, and add client.events.on().listen(print); Example: JosefWN@3a9dcaa If you try running the This also makes it possible for library users to listen for and act on any events they choose, without imposing a specific logger or event handler on them (of course, we would still handle the events internally as required, but we wouldn't programmatically obscure anything from the library user). If we are missing important events for debugging we can just add more of them. What do you think? Another thing we could do when users encounter issues is to ask them to provide us with a minimal example reproducing that issue. Shifting the burden of proof to the person with the problem will reduce the debugging load on us even further, as we could just run their problematic example code, or a very similar piece of code, against another server. |
This sounds good to me, the existing logging did need to go, I'll have a look at log_events.dart but I'm happy with this approach. |
This is an attempt to fix:
My work was loosely inspired by https://pub.dev/packages/http but with an adaptation to how CoAP clients commonly work in other languages (at least those I like 😅). See the examples to get a feeling for things. TLDR: this PR aims to make the library more native to Dart, to better leverage its strengths. Hopefully I'll manage to make a good case for it below...
Unsure:
validate
method on the client, I figured either the user builds his request (for example for etag validation, usingclient.send
), or the user relies on the client for building the entire request (for exampleclient.get('hello')
). This felt like a bit of a hybrid.Major stuff:
get(...)
,post(...)
etc.), a more manualsend(...)
for advanced requests and its counterpartobserve(...)
for streaming, which I suppose is not used often enough to warrant a request builder?meta
package with its@protected
annotation for those I couldn't hide completely (will give static analysis warnings). It's now much harder for the user to "do the wrong things".print()
calls.CoapIChannel
andCoapIDeliverer
and their implementations were seemingly not serving any purpose, even less so after I went from passing the response back to the request, to using the event bus to communicate. This in turn removes the need for theCoapNetworkManager
since each client now only has one endpoint (less risk of API user mistakes), as well as the settingpoolUdpConnectionsByClient
. The pooling doesn't have any drawbacks as far as I can see, the more separation the better?You can even run multiple observe and different requests concurrently (see
examples/get_observe_async.dart
).Minor stuff:
_doPrepare
called one line too late)block1
requests (need it for matching in the client)test/issues
folder withexamples
notify
anderror
onobserve
, they were unused arguments from what I could seeraw_request_creation.dart
as that would no longer be supported (no need to worry about preparing the request manually)Performance vs 3.5.0 (in parentheses), as baseline before all of my changes:
Nothing scientific, just a couple of quick checks to ensure my changes that went out in v3.6.0 and in this PR are not making things slower.