dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
140 lines
4.6 KiB
Python
140 lines
4.6 KiB
Python
import json
|
|
import logging
|
|
from collections import deque
|
|
|
|
import time
|
|
from typing import Text, Optional, Union, Deque, Dict, Any
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
NO_TICKET_ISSUED = -1 # index of latest issued ticket if no tickets exist
|
|
|
|
|
|
class Ticket:
|
|
def __init__(self, number: int, expires: float) -> None:
|
|
self.number = number
|
|
self.expires = expires
|
|
|
|
def has_expired(self) -> bool:
|
|
return time.time() > self.expires
|
|
|
|
def as_dict(self) -> Dict[Text, Any]:
|
|
return dict(number=self.number, expires=self.expires)
|
|
|
|
def dumps(self) -> Text:
|
|
"""Return json dump of `Ticket` as dictionary."""
|
|
return json.dumps(self.as_dict())
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[Text, Union[int, float]]) -> "Ticket":
|
|
"""Creates `Ticket` from dictionary."""
|
|
return cls(number=data["number"], expires=data["expires"])
|
|
|
|
def __repr__(self) -> Text:
|
|
return f"Ticket(number: {self.number}, expires: {self.expires})"
|
|
|
|
|
|
class TicketLock:
|
|
"""Locking mechanism that issues tickets managing access to conversation IDs.
|
|
|
|
Tickets are issued in the order in which they are requested. A detailed
|
|
explanation of the ticket lock algorithm can be found at
|
|
http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf#page=13
|
|
"""
|
|
|
|
def __init__(
|
|
self, conversation_id: Text, tickets: Optional[Deque[Ticket]] = None
|
|
) -> None:
|
|
self.conversation_id = conversation_id
|
|
self.tickets = tickets or deque()
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[Text, Any]) -> "TicketLock":
|
|
"""Create `TicketLock` from dictionary."""
|
|
tickets = [Ticket.from_dict(json.loads(d)) for d in data.get("tickets", [])]
|
|
return cls(data.get("conversation_id"), deque(tickets))
|
|
|
|
def dumps(self) -> Text:
|
|
"""Return json dump of `TicketLock`."""
|
|
tickets = [ticket.dumps() for ticket in self.tickets]
|
|
return json.dumps(dict(conversation_id=self.conversation_id, tickets=tickets))
|
|
|
|
def is_locked(self, ticket_number: int) -> bool:
|
|
"""Return whether `ticket_number` is locked.
|
|
|
|
Returns:
|
|
True if `now_serving` is not equal to `ticket`.
|
|
"""
|
|
return self.now_serving != ticket_number
|
|
|
|
def issue_ticket(self, lifetime: float) -> int:
|
|
"""Issue a new ticket and return its number."""
|
|
self.remove_expired_tickets()
|
|
number = self.last_issued + 1
|
|
ticket = Ticket(number, time.time() + lifetime)
|
|
self.tickets.append(ticket)
|
|
|
|
return number
|
|
|
|
def remove_expired_tickets(self) -> None:
|
|
"""Remove expired tickets."""
|
|
# iterate over copy of self.tickets so we can remove items
|
|
for ticket in list(self.tickets):
|
|
if ticket.has_expired():
|
|
self.tickets.remove(ticket)
|
|
|
|
@property
|
|
def last_issued(self) -> int:
|
|
"""Return number of the ticket that was last added.
|
|
|
|
Returns:
|
|
Number of `Ticket` that was last added. `NO_TICKET_ISSUED` if no
|
|
tickets exist.
|
|
"""
|
|
ticket_number = self._ticket_number_for(-1)
|
|
|
|
return ticket_number if ticket_number is not None else NO_TICKET_ISSUED
|
|
|
|
@property
|
|
def now_serving(self) -> Optional[int]:
|
|
"""Get number of the ticket to be served next.
|
|
|
|
Returns:
|
|
Number of `Ticket` that is served next. 0 if no `Ticket` exists.
|
|
"""
|
|
return self._ticket_number_for(0) or 0
|
|
|
|
def _ticket_number_for(self, ticket_index: int) -> Optional[int]:
|
|
"""Get ticket number for `ticket_index`.
|
|
|
|
Returns:
|
|
Ticket number for `Ticket` with index `ticket_index`. None if there are no
|
|
tickets, or if `ticket_index` is out of bounds of `self.tickets`.
|
|
"""
|
|
self.remove_expired_tickets()
|
|
|
|
try:
|
|
return self.tickets[ticket_index].number
|
|
except IndexError:
|
|
return None
|
|
|
|
def _ticket_for_ticket_number(self, ticket_number: int) -> Optional[Ticket]:
|
|
"""Return ticket for `ticket_number`."""
|
|
self.remove_expired_tickets()
|
|
|
|
return next((t for t in self.tickets if t.number == ticket_number), None)
|
|
|
|
def is_someone_waiting(self) -> bool:
|
|
"""Return whether someone is waiting for the lock to become available.
|
|
|
|
Returns:
|
|
True if the `self.tickets` queue has length greater than 0.
|
|
"""
|
|
return len(self.tickets) > 0
|
|
|
|
def remove_ticket_for(self, ticket_number: int) -> None:
|
|
"""Remove `Ticket` for `ticket_number."""
|
|
ticket = self._ticket_for_ticket_number(ticket_number)
|
|
if ticket:
|
|
self.tickets.remove(ticket)
|