-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into task-logging-test
- Loading branch information
Showing
96 changed files
with
5,800 additions
and
787 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
[run] | ||
branch = True | ||
source = ./labthings | ||
omit = .venv/*, labthings/server/wsgi/*, , labthings/server/monkey.py | ||
concurrency = greenlet | ||
|
||
[report] | ||
# Regexes for lines to exclude from consideration | ||
exclude_lines = | ||
# Have to re-enable the standard pragma | ||
pragma: no cover | ||
|
||
# Don't complain about missing debug-only code: | ||
def __repr__ | ||
if self\.debug | ||
|
||
# Don't complain if tests don't hit defensive assertion code: | ||
raise AssertionError | ||
raise NotImplementedError | ||
|
||
# Don't complain if non-runnable code isn't run: | ||
if 0: | ||
if __name__ == .__main__.: | ||
|
||
ignore_errors = True | ||
|
||
[html] | ||
directory = coverage_html_report |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[flake8] | ||
max-line-length = 88 | ||
exclude = tests/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
name: CI | ||
|
||
on: [push] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v1 | ||
with: | ||
fetch-depth: 1 | ||
|
||
- name: Set up Python 3.7 | ||
uses: actions/setup-python@v1 | ||
with: | ||
python-version: 3.7 | ||
|
||
- name: Install Poetry | ||
uses: dschep/install-poetry-action@v1.3 | ||
|
||
- name: Cache Poetry virtualenv | ||
uses: actions/cache@v1 | ||
id: cache | ||
with: | ||
path: ~/.virtualenvs | ||
key: poetry-${{ hashFiles('**/poetry.lock') }} | ||
restore-keys: | | ||
poetry-${{ hashFiles('**/poetry.lock') }} | ||
- name: Set Poetry config | ||
run: | | ||
poetry config virtualenvs.in-project false | ||
poetry config virtualenvs.path ~/.virtualenvs | ||
- name: Install Dependencies | ||
run: poetry install | ||
if: steps.cache.outputs.cache-hit != 'true' | ||
|
||
- name: Code Quality | ||
run: poetry run black . --check | ||
|
||
- name: Test with pytest | ||
run: poetry run pytest --cov-report term-missing --cov-report=xml --cov=labthings ./tests | ||
|
||
- name: Upload coverage to Codecov | ||
uses: codecov/codecov-action@v1 | ||
with: | ||
file: ./coverage.xml | ||
flags: unittests | ||
name: codecov-umbrella | ||
fail_ci_if_error: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from gevent.hub import getcurrent | ||
import gevent | ||
import time | ||
import logging | ||
|
||
from gevent.monkey import get_original | ||
|
||
# Guarantee that Task threads will always be proper system threads, regardless of Gevent patches | ||
Event = get_original("threading", "Event") | ||
|
||
|
||
class ClientEvent(object): | ||
""" | ||
An event-signaller object with per-client setting and waiting. | ||
A client can be any Greenlet or native Thread. This can be used, for example, | ||
to signal to clients that new data is available | ||
""" | ||
|
||
def __init__(self): | ||
self.events = {} | ||
|
||
def wait(self, timeout: int = 5): | ||
"""Wait for the next data frame (invoked from each client's thread).""" | ||
ident = id(getcurrent()) | ||
if ident not in self.events: | ||
# this is a new client | ||
# add an entry for it in the self.events dict | ||
# each entry has two elements, a threading.Event() and a timestamp | ||
self.events[ident] = [Event(), time.time()] | ||
|
||
# We have to reimplement event waiting here as we need native thread events to allow gevent context switching | ||
wait_start = time.time() | ||
while not self.events[ident][0].is_set(): | ||
now = time.time() | ||
if now - wait_start > timeout: | ||
return False | ||
gevent.sleep(0) | ||
return True | ||
|
||
def set(self, timeout=5): | ||
"""Signal that a new frame is available.""" | ||
now = time.time() | ||
remove = None | ||
for ident, event in self.events.items(): | ||
if not event[0].is_set(): | ||
# if this client's event is not set, then set it | ||
# also update the last set timestamp to now | ||
event[0].set() | ||
event[1] = now | ||
else: | ||
# if the client's event is already set, it means the client | ||
# did not process a previous frame | ||
# if the event stays set for more than `timeout` seconds, then assume | ||
# the client is gone and remove it | ||
if now - event[1] >= timeout: | ||
remove = ident | ||
if remove: | ||
del self.events[remove] | ||
|
||
def clear(self): | ||
"""Clear frame event, once processed.""" | ||
ident = id(getcurrent()) | ||
if ident not in self.events: | ||
logging.error(f"Mismatched ident. Current: {ident}, available:") | ||
logging.error(self.events.keys()) | ||
return False | ||
self.events[id(getcurrent())][0].clear() | ||
return True |
Oops, something went wrong.