-
-
Notifications
You must be signed in to change notification settings - Fork 595
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
Ensure tile-loaded event completionCallback is called only once. #2282
Conversation
…k when context2D used after cache creation.
Possible fix for #2277 |
Hmm not really friendly solution with tests :/ |
the issue is
so now it kind of works if the callback is not asynchronous, but does not work vice versa (as intended with tests). Also, the callback is called immediately instead of waiting for the last caller who got a completion callback. Not sure what is better or worse. |
…l scenario of async completion notification with additional guarding flags.
Implementation changed to use flags that guard completion (#2277 (comment)). Still there might be issue when early completion (completion called immediately), and another plugin attaches context2D. Possibly add also flag that prevents completion before the event finishes? |
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.
Looks good to me. Just a quick comment on the error.
Still there might be issue when early completion (completion called immediately), and another plugin attaches context2D. Possibly add also flag that prevents completion before the event finishes?
Seems reasonable. I suppose we could just call getCompletionCallback
before we send out the event, and then call that callback at the end. Come to think of it, that would probably make it so we don't need completed
anymore!
…Improve getCompletionCallback docs.
In the end, I changed the error message as well as docs to be yet more explicit, it will not hurt. Using completion without async has no reason, now early completion can happen only when one hacks the semaphore with two completion calls. |
This looks to me like it should work as intended. A couple of thoughts:
|
@pearcetm I had just last week or so PR on promise support in events, which would solve this as well (the event could just behave as synchronized await Promise.all()). We decided not to include it at the end since it brings a lot of complexity without a strong motivation why it is really needed to be in the core library (I am still using it in my app by extending EventSource). So I guess it is still not a must-have reason and we rather keep the old API if possible, because compatibility. Offtopic: to be honest, the first thing I would like with ES6 introduction would be to rewrite manual inheritance on all OSD classes 😄
I do. The filtering plugin that started this PR does pretty wild coding to call the callback at the end of filter application - for no reason (except the bugs 😄 ). It lets them know: do not touch if you don't know you need it. |
I saw that PR and discussion. In this case, though, it would be a purely internal use of |
I don't think the filtering plugin is "wild coding" - it is intended to support arbitrary combinations of sync and async filter operations. Since async is allowed, it gets a callback, and asks each filter to indicate when it's completed, and then calls the callback. To avoid |
I agree that we don't need the warning against using it synchronously. It'll work just fine with this fix, and it's a valid use case. We should definitely consider the possibility of introducing ES6. I'll start a new issue for that. Either way, I don't think we need a promise here... We already have an implementation that works, and adding the first promise is a big step, even if it's just internally. As far as I'm concerned, I think this is ready to land once the "note" is removed from the docs. It's amusing to me how simple this has become from what seemed like a complicated issue at first! It's great working through these things together :) |
Yup! The tough part was drilling down far enough to figure out the root cause. Other than improving documentation and error messages, the ultimate fix boils down to just 1 or 2 lines of code changes :)
I completely agree that since ES6 support hasn't been introduced yet, this isn't the hill to fight that battle on. As you say it isn't necessary since this implementation works. But the Promise-based approach does make for quite clean code, and if ES6 had been introduced already, it would have been almost "self-documenting" because it fits the needs of this function so closely. All that to say, I am in total support of the issue you opened about adding ES6! |
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.
Lovely, thank you!
The PR also errors when context2D is set after cache creation.