You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Multi service browsers of the same type create excessive queries #721
If we are already browsing for a type we should suppress additional question generation. We need to call soon thread safe coordination when adding and removing a service browser
If we have a ServiceQueryCoordinator that does all the sends in event loop, the ServiceBrowser thread can simplify be a SimpleQueue that reads and fires handlers. Maybe reuse the original async sender code
We still have to solve the waiting in serviceinfo as well. We could import the async code and run it in the event loop with run coroutine thread safe. We would need the same safety to throw if someone tried to do that from the event loop. Like we have with the close function
Then we can get rid of all the notify wakes which are really expensive when there is a lot of traffic
Then we do
start send loop task if none running, otherwise update the data structs, reset the delay/next_time for everything just registered, and async_notify_all
on deregister
update data structs, cancel the task if nothing left.
on loop.
Similar to now, but when a type is ready we built sets of qu or qm questions for each target group (addr, port, QuestionType.QM) for any like sets, then fire off the questions to the addr/port/type for each group we built. As an optimization we could see which target groups have the same sets of questions and only build them once and still fire off to all the dests.
# grep 'was suppressed by the question history' home-assistant.log
2021-06-20 18:16:39 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:25:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:25:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:28:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:28:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:34:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
2021-06-20 18:34:37 DEBUG (MainThread) [zeroconf] Asking ptr[question,QM,in,_googlecast._tcp.local.] was suppressed by the question history
Activity
bdraco commentedon Jun 18, 2021
Maybe move ServiceBrowser* into _services.browser and the. Add a ServiceBrowserCoorindator class that manages the next times
bdraco commentedon Jun 18, 2021
Example here is that home assistant uses a browser for discovery and pychromecast starts another one
bdraco commentedon Jun 19, 2021
This is a bit better after #737 since it will at least share known answers, but its still going to generate more queries
bdraco commentedon Jun 19, 2021
At least after #737 we are sending the queries at the same time so there is a greater chance of Duplicate Question Suppression https://datatracker.ietf.org/doc/html/rfc6762#section-7.3
grep _googlecast._tcp.local home-assistant.logbdraco commentedon Jun 19, 2021
Need to be careful not to coordinate QU / addr browsers
bdraco commentedon Jun 19, 2021
If we have a ServiceQueryCoordinator that does all the sends in event loop, the ServiceBrowser thread can simplify be a SimpleQueue that reads and fires handlers. Maybe reuse the original async sender code
bdraco commentedon Jun 19, 2021
That would make everything much simpler and we would be using the preferred pythonic way to communicate between threads.
bdraco commentedon Jun 19, 2021
Maybe a set_next_time for type_, addr, port?
bdraco commentedon Jun 19, 2021
We still have to solve the waiting in serviceinfo as well. We could import the async code and run it in the event loop with run coroutine thread safe. We would need the same safety to throw if someone tried to do that from the event loop. Like we have with the close function
Then we can get rid of all the notify wakes which are really expensive when there is a lot of traffic
Run ServiceBrowser queries in the event loop
bdraco commentedon Jun 19, 2021
I think we just move the next time. Also we can stop the waits since we can use asyncio.Event.
bdraco commentedon Jun 19, 2021
We can make this so much simpler now
async_update_records_complete can just add to the queue or fire the event.
Then we have the browser coordinator sending the queries in a task
In the record processing we can tell the coordinator to schedule a query sooner and set a condition to wake it up
bdraco commentedon Jun 20, 2021
Maybe
QuestionType.QM,QuestionType.QUcancel = ServiceBrowserCoordinator.async_register(types, addr, port, QuestionType.QM)
cancel() to deregister
Then we do
start send loop task if none running, otherwise update the data structs, reset the delay/next_time for everything just registered, and async_notify_all
on deregister
update data structs, cancel the task if nothing left.
on loop.
Similar to now, but when a type is ready we built sets of qu or qm questions for each target group
(addr, port, QuestionType.QM)for any like sets, then fire off the questions to the addr/port/type for each group we built. As an optimization we could see which target groups have the same sets of questions and only build them once and still fire off to all the dests.bdraco commentedon Jun 20, 2021
Probably enumerate types and then create buckets of question types and put each type into the bucket. Then generate questions from buckets and send
bdraco commentedon Jun 20, 2021
Started building the Coordinator and I think its the wrong solution
We need internal duplicate question suppression
https://datatracker.ietf.org/doc/html/rfc6762#section-7.3
bdraco commentedon Jun 20, 2021
That does it and it works for other types as well
bdraco commentedon Jun 20, 2021