Skip to content

Commit 0483409

Browse files
authored
Merge pull request #10 from karellen/gha_with_additional_pythons
Add GHA
2 parents e6746a3 + 9e14c6a commit 0483409

19 files changed

+373
-393
lines changed

.github/workflows/build.yml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: geventmp
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
push:
7+
branches:
8+
- master
9+
jobs:
10+
build:
11+
runs-on: ${{ matrix.os }}
12+
continue-on-error: false
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os:
17+
- ubuntu-latest
18+
# - windows-latest
19+
# - macosx-latest
20+
python-version:
21+
- '3.10'
22+
- '3.9'
23+
- '3.8'
24+
- '3.7'
25+
- '3.6'
26+
- 'pypy-3.7'
27+
env:
28+
DEPLOY_PYTHONS: "3.9"
29+
DEPLOY_OSES: "Linux"
30+
TWINE_USERNAME: __token__
31+
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
steps:
34+
- shell: bash
35+
if: |
36+
github.event_name == 'push' &&
37+
contains(env.DEPLOY_OSES, runner.os) &&
38+
contains(env.DEPLOY_PYTHONS, matrix.python-version)
39+
run: |
40+
echo "PYB_EXTRA_ARGS=+upload" >> $GITHUB_ENV
41+
- uses: pybuilder/build@master
42+
with:
43+
python-version: ${{ matrix.python-version }}
44+
pyb-extra-args: ${{ env.PYB_EXTRA_ARGS }}
45+
build-summary:
46+
if: success() || failure()
47+
runs-on: ubuntu-latest
48+
name: Build Summary
49+
needs: build
50+
steps:
51+
- name: Check build matrix status
52+
if: needs.build.result != 'success'
53+
run: exit 1

.idea/geventmp.iml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/markdown.xml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.travis.yml

-50
This file was deleted.

README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
.. image:: https://img.shields.io/gitter/room/karellen/Lobby?logo=gitter
66
:target: https://gitter.im/karellen/Lobby
77
:alt: Gitter
8-
.. image:: https://img.shields.io/travis/karellen/geventmp/master?logo=travis
9-
:target: https://travis-ci.org/karellen/geventmp
8+
.. image:: https://img.shields.io/github/workflow/status/karellen/geventmp/geventmp/master
9+
:target: https://github.com/karellen/geventmp/actions/workflows/build.yml
1010
:alt: Build Status
1111
.. image:: https://img.shields.io/coveralls/github/karellen/geventmp/master?logo=coveralls
1212
:target: https://coveralls.io/r/karellen/geventmp?branch=master

build.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
# -*- coding: utf-8 -*-
2+
# Copyright 2019 Karellen, Inc. and contributors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
216
from pybuilder.core import (use_plugin, init, Author, before, Dependency)
317

418
use_plugin("python.core")
@@ -11,7 +25,7 @@
1125
use_plugin("copy_resources")
1226

1327
name = "geventmp"
14-
version = "0.0.1"
28+
version = "0.0.2.dev"
1529

1630
summary = "Multiprocessing Gevent Extension"
1731
authors = [Author("Karellen, Inc.", "supervisor@karellen.co")]
@@ -24,7 +38,7 @@
2438
}
2539
license = "Apache License, Version 2.0"
2640

27-
requires_python = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3,!=3.4"
41+
requires_python = ">=3.6"
2842

2943
default_task = ["analyze", "publish"]
3044

@@ -63,11 +77,11 @@ def set_properties(project):
6377

6478
project.set_property("distutils_classifiers", [
6579
"License :: OSI Approved :: Apache Software License",
66-
"Programming Language :: Python :: 2.7",
67-
"Programming Language :: Python :: 3.5",
6880
"Programming Language :: Python :: 3.6",
6981
"Programming Language :: Python :: 3.7",
7082
"Programming Language :: Python :: 3.8",
83+
"Programming Language :: Python :: 3.9",
84+
"Programming Language :: Python :: 3.10",
7185
"Programming Language :: Python :: Implementation :: CPython",
7286
"Operating System :: MacOS :: MacOS X",
7387
"Operating System :: POSIX",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2019 Karellen, Inc. and contributors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import threading
17+
import trace
18+
from multiprocessing.connection import Listener, Connection
19+
from multiprocessing.managers import SyncManager, Server
20+
from queue import Queue
21+
from time import sleep
22+
23+
from gevent import spawn, monkey
24+
from gevent.hub import wait, idle, get_hub
25+
from gevent.util import format_run_info
26+
from multiprocessing.util import get_logger
27+
28+
from geventmp.monkey import GEVENT_SAVED_MODULE_SETTINGS
29+
30+
REQUEST_COUNT = 10
31+
QUEUE_SIZE = 3
32+
QUEUE_DEPTH = 10
33+
34+
35+
def idle_watcher():
36+
return
37+
logger = get_logger()
38+
prev = None
39+
while True:
40+
idle()
41+
current = format_run_info()
42+
if prev != current:
43+
prev = current
44+
logger.warning("\n".join(current))
45+
sleep(0.01)
46+
47+
48+
def instrument_conn(conn):
49+
_old_send = conn.send
50+
_old_recv = conn.recv
51+
52+
logger = get_logger()
53+
thread_name = threading.current_thread().name
54+
55+
def new_send(obj):
56+
logger.info("%s: %s: sending %r", thread_name, conn.fileno(), obj)
57+
return _old_send(obj)
58+
59+
def new_recv():
60+
obj = _old_recv()
61+
logger.info("%s: %s: received %r", thread_name, conn.fileno(), obj)
62+
return obj
63+
64+
conn.send = new_send
65+
conn.recv = new_recv
66+
67+
return conn
68+
69+
70+
class TestServer(Server):
71+
def serve_client(self, conn):
72+
return super().serve_client(instrument_conn(conn))
73+
74+
75+
class TestSyncManager(SyncManager):
76+
_Server = TestServer
77+
78+
79+
def manager_init():
80+
spawn(idle_watcher)
81+
82+
83+
def manager_process(addr, do_trace=False):
84+
if not monkey.saved[GEVENT_SAVED_MODULE_SETTINGS].get("geventmp"):
85+
raise RuntimeError("GeventMP patch has not run!")
86+
87+
if do_trace:
88+
trace.Trace(count=0).runfunc(_manager_process, addr)
89+
else:
90+
_manager_process(addr)
91+
92+
93+
def _manager_process(addr):
94+
logger = get_logger()
95+
spawn(idle_watcher)
96+
try:
97+
listener: Listener = Listener(addr, "AF_UNIX")
98+
99+
with listener:
100+
manager = SyncManager()
101+
manager.start(manager_init)
102+
try:
103+
def process_queue(q: Queue, idx: int):
104+
for val_idx in range(0, QUEUE_DEPTH):
105+
put_string = f"Request #{idx}, Value #{val_idx}"
106+
logger.info(f"**** Sending {put_string} on {q._id}")
107+
q.put(put_string)
108+
logger.info(f"**** Sent {put_string} on {q._id}")
109+
sleep(0.05)
110+
111+
logger.info(f"**** Putting None in queue request #{idx} to empty on {q._id}")
112+
q.put(None)
113+
logger.info(f"**** Waiting for queue request #{idx} to empty on {q._id}")
114+
q.join()
115+
logger.info(f"**** All done with request #{idx} on {q._id}")
116+
117+
def process_conn(conn: Connection, idx: int):
118+
with conn:
119+
logger.info(f"**** Accepted request #{idx}")
120+
q: Queue = manager.Queue(QUEUE_SIZE)
121+
logger.info(f"**** Passing request #{idx} queue {q._id}")
122+
conn.send(q)
123+
logger.info(f"**** Passed request #{idx} queue {q._id}")
124+
125+
spawn(process_queue, q, idx)
126+
127+
for i in range(0, REQUEST_COUNT):
128+
spawn(process_conn, listener.accept(), i)
129+
130+
wait(timeout=60)
131+
# logger.warning("\n".join(format_run_info()))
132+
finally:
133+
manager.shutdown()
134+
finally:
135+
get_hub().destroy()

0 commit comments

Comments
 (0)