Skip to content

Commit

Permalink
feat: significantly improve efficiency of the ServiceBrowser scheduler (
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Dec 16, 2023
1 parent 7de655b commit c65d869
Show file tree
Hide file tree
Showing 7 changed files with 1,083 additions and 479 deletions.
2 changes: 1 addition & 1 deletion examples/browser.py
Expand Up @@ -66,7 +66,7 @@ def on_service_state_change(

zeroconf = Zeroconf(ip_version=ip_version)

services = ["_http._tcp.local.", "_hap._tcp.local."]
services = ["_http._tcp.local.", "_hap._tcp.local.", "_esphomelib._tcp.local.", "_airplay._tcp.local."]
if args.find:
services = list(ZeroconfServiceTypes.find(zc=zeroconf))

Expand Down
87 changes: 57 additions & 30 deletions src/zeroconf/_services/browser.pxd
Expand Up @@ -14,79 +14,106 @@ cdef bint TYPE_CHECKING
cdef object cached_possible_types
cdef cython.uint _EXPIRE_REFRESH_TIME_PERCENT, _MAX_MSG_TYPICAL, _DNS_PACKET_HEADER_LEN
cdef cython.uint _TYPE_PTR
cdef object _CLASS_IN
cdef object SERVICE_STATE_CHANGE_ADDED, SERVICE_STATE_CHANGE_REMOVED, SERVICE_STATE_CHANGE_UPDATED
cdef cython.set _ADDRESS_RECORD_TYPES
cdef float RESCUE_RECORD_RETRY_TTL_PERCENTAGE

cdef object _MDNS_PORT, _BROWSER_TIME

cdef object QU_QUESTION

cdef object _FLAGS_QR_QUERY

cdef object heappop, heappush

cdef class _ScheduledPTRQuery:

cdef public str alias
cdef public str name
cdef public unsigned int ttl
cdef public bint cancelled
cdef public double expire_time_millis
cdef public double when_millis

cdef class _DNSPointerOutgoingBucket:

cdef public object now
cdef public double now_millis
cdef public DNSOutgoing out
cdef public cython.uint bytes

cpdef add(self, cython.uint max_compressed_size, DNSQuestion question, cython.set answers)

@cython.locals(cache=DNSCache, question_history=QuestionHistory, record=DNSRecord, qu_question=bint)
cpdef generate_service_query(
cpdef list generate_service_query(
object zc,
double now,
list type_,
double now_millis,
set types_,
bint multicast,
object question_type
)

@cython.locals(answer=DNSPointer, query_buckets=list, question=DNSQuestion, max_compressed_size=cython.uint, max_bucket_size=cython.uint, query_bucket=_DNSPointerOutgoingBucket)
cdef _group_ptr_queries_with_known_answers(object now, object multicast, cython.dict question_with_known_answers)
cdef list _group_ptr_queries_with_known_answers(double now_millis, bint multicast, cython.dict question_with_known_answers)

cdef class QueryScheduler:

cdef cython.set _types
cdef cython.dict _next_time
cdef object _first_random_delay_interval
cdef cython.dict _delay
cdef object _zc
cdef set _types
cdef str _addr
cdef int _port
cdef bint _multicast
cdef tuple _first_random_delay_interval
cdef double _min_time_between_queries_millis
cdef object _loop
cdef unsigned int _startup_queries_sent
cdef public dict _next_scheduled_for_alias
cdef public list _query_heap
cdef object _next_run
cdef double _clock_resolution_millis
cdef object _question_type

cpdef void schedule_ptr_first_refresh(self, DNSPointer pointer)

cdef void _schedule_ptr_refresh(self, DNSPointer pointer, double expire_time_millis, double refresh_time_millis)

cdef void _schedule_ptr_query(self, _ScheduledPTRQuery scheduled_query)

cpdef millis_to_wait(self, object now)
@cython.locals(scheduled=_ScheduledPTRQuery)
cpdef void cancel_ptr_refresh(self, DNSPointer pointer)

cpdef reschedule_type(self, object type_, object next_time)
@cython.locals(current=_ScheduledPTRQuery, expire_time=double)
cpdef void reschedule_ptr_first_refresh(self, DNSPointer pointer)

cpdef process_ready_types(self, object now)
@cython.locals(ttl_millis='unsigned int', additional_wait=double, next_query_time=double)
cpdef void schedule_rescue_query(self, _ScheduledPTRQuery query, double now_millis, float additional_percentage)

cpdef void _process_startup_queries(self)

@cython.locals(query=_ScheduledPTRQuery, next_scheduled=_ScheduledPTRQuery, next_when=double)
cpdef void _process_ready_types(self)

cpdef void async_send_ready_queries(self, bint first_request, double now_millis, set ready_types)

cdef class _ServiceBrowserBase(RecordUpdateListener):

cdef public cython.set types
cdef public object zc
cdef DNSCache _cache
cdef object _loop
cdef public object addr
cdef public object port
cdef public object multicast
cdef public object question_type
cdef public cython.dict _pending_handlers
cdef public object _service_state_changed
cdef public QueryScheduler query_scheduler
cdef public bint done
cdef public object _first_request
cdef public object _next_send_timer
cdef public object _query_sender_task

cpdef _generate_ready_queries(self, object first_request, object now)

cpdef void _enqueue_callback(self, object state_change, object type_, object name)

@cython.locals(record_update=RecordUpdate, record=DNSRecord, cache=DNSCache, service=DNSRecord, pointer=DNSPointer)
cpdef void async_update_records(self, object zc, double now, cython.list records)

cpdef cython.list _names_matching_types(self, object types)

cpdef reschedule_type(self, object type_, object now, object next_time)

cpdef _fire_service_state_changed_event(self, cython.tuple event)

cpdef _async_send_ready_queries_schedule_next(self)

cpdef _async_schedule_next(self, object now)

cpdef _async_send_ready_queries(self, object now)

cpdef _cancel_send_timer(self)

cpdef void async_update_records_complete(self)

0 comments on commit c65d869

Please sign in to comment.