aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjason2017-01-23 20:06:18 -0700
committerjason2017-01-24 10:13:40 -0700
commitb340ea15add30d136eb46b8998aee0ffb1a72115 (patch)
tree9e709a101adf8b3a804400a770565edf202e6651
parent1d9e4e103bd611cda4f3208d8c0921f6859729dd (diff)
downloadeventmq-b340ea15add30d136eb46b8998aee0ffb1a72115.tar.gz
eventmq-b340ea15add30d136eb46b8998aee0ffb1a72115.zip
Update the pep8 goodness and test with circle and flake8
-rw-r--r--.flake86
-rw-r--r--bin/logwatcher.py2
-rw-r--r--circle.yml5
-rw-r--r--docs/conf.py109
-rw-r--r--eventmq/client/jobs.py2
-rw-r--r--eventmq/client/messages.py5
-rw-r--r--eventmq/conf.py2
-rw-r--r--eventmq/jobmanager.py14
-rw-r--r--eventmq/log.py4
-rw-r--r--eventmq/pub.py10
-rw-r--r--eventmq/publisher.py4
-rw-r--r--eventmq/receiver.py1
-rw-r--r--eventmq/router.py40
-rw-r--r--eventmq/scheduler.py18
-rw-r--r--eventmq/subscriber.py4
-rw-r--r--eventmq/tests/test_client_jobs.py1
-rw-r--r--eventmq/tests/test_jobmanager.py4
-rw-r--r--eventmq/tests/test_receiver.py6
-rw-r--r--eventmq/tests/test_router.py11
-rw-r--r--eventmq/tests/test_scheduler.py5
-rw-r--r--eventmq/tests/test_sender.py2
-rw-r--r--eventmq/tests/test_utils.py4
-rw-r--r--eventmq/tests/test_utils_encoding.py1
-rw-r--r--eventmq/tests/utils.py3
-rw-r--r--eventmq/utils/classes.py2
-rw-r--r--eventmq/utils/encoding.py2
-rw-r--r--eventmq/utils/functions.py2
-rw-r--r--eventmq/utils/messages.py2
-rw-r--r--eventmq/utils/timeutils.py2
-rw-r--r--eventmq/worker.py6
-rw-r--r--requirements_.txt19
-rw-r--r--setup.py17
32 files changed, 151 insertions, 164 deletions
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..657b97b
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,6 @@
1[flake8]
2# Packages that should be considered local to the app. These need to be in the last group
3application-import-names=eventmq
4
5# Same as pep8 but enforces alphabetical ordering
6import-order-style=google \ No newline at end of file
diff --git a/bin/logwatcher.py b/bin/logwatcher.py
index f83c905..dd2860f 100644
--- a/bin/logwatcher.py
+++ b/bin/logwatcher.py
@@ -13,4 +13,4 @@ while True:
13 13
14 if events.get(s) == zmq.POLLIN: 14 if events.get(s) == zmq.POLLIN:
15 msg = s.recv_multipart() 15 msg = s.recv_multipart()
16 print msg 16 print msg # noqa
diff --git a/circle.yml b/circle.yml
index 6a8652b..8ad95de 100644
--- a/circle.yml
+++ b/circle.yml
@@ -5,8 +5,9 @@ machine:
5 - redis 5 - redis
6test: 6test:
7 override: 7 override:
8 - pip install --upgrade -r requirements_.txt 8 - pip install -e .[testing]
9 - nosetests-2.7 --with-coverage --cover-inclusive --cover-package=eventmq --cover-tests 9 - nosetests-2.7 --with-coverage --cover-inclusive --cover-package=eventmq --cover-tests
10 - pip3.5 install --upgrade -r requirements_.txt 10 - pip3.5 install -e .[testing]
11 - /opt/circleci/python/3.5.2/bin/nosetests-3.4 11 - /opt/circleci/python/3.5.2/bin/nosetests-3.4
12 - find . -name \*.py -print | xargs flake8 --show-source --statistics
12 - coverage html -d "$CIRCLE_ARTIFACTS/coverage" 13 - coverage html -d "$CIRCLE_ARTIFACTS/coverage"
diff --git a/docs/conf.py b/docs/conf.py
index 1e28fa9..7cc2c14 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -11,21 +11,16 @@
11# 11#
12# All configuration values have a default; values that are commented out 12# All configuration values have a default; values that are commented out
13# serve to show the default. 13# serve to show the default.
14
15import sys
16import os
17import shlex
18
19import eventmq # for __version__ 14import eventmq # for __version__
20# If extensions (or modules to document with autodoc) are in another directory, 15# If extensions (or modules to document with autodoc) are in another directory,
21# add these directories to sys.path here. If the directory is relative to the 16# add these directories to sys.path here. If the directory is relative to the
22# documentation root, use os.path.abspath to make it absolute, like shown here. 17# documentation root, use os.path.abspath to make it absolute, like shown here.
23#sys.path.insert(0, os.path.abspath('.')) 18# sys.path.insert(0, os.path.abspath('.'))
24 19
25# -- General configuration ------------------------------------------------ 20# -- General configuration ------------------------------------------------
26 21
27# If your documentation needs a minimal Sphinx version, state it here. 22# If your documentation needs a minimal Sphinx version, state it here.
28#needs_sphinx = '1.0' 23# needs_sphinx = '1.0'
29 24
30# Add any Sphinx extension module names here, as strings. They can be 25# Add any Sphinx extension module names here, as strings. They can be
31# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 26# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -46,7 +41,7 @@ templates_path = ['_templates']
46source_suffix = '.rst' 41source_suffix = '.rst'
47 42
48# The encoding of source files. 43# The encoding of source files.
49#source_encoding = 'utf-8-sig' 44# source_encoding = 'utf-8-sig'
50 45
51# The master toctree document. 46# The master toctree document.
52master_doc = 'index' 47master_doc = 'index'
@@ -74,9 +69,9 @@ language = None
74 69
75# There are two options for replacing |today|: either, you set today to some 70# There are two options for replacing |today|: either, you set today to some
76# non-false value, then it is used: 71# non-false value, then it is used:
77#today = '' 72# today = ''
78# Else, today_fmt is used as the format for a strftime call. 73# Else, today_fmt is used as the format for a strftime call.
79#today_fmt = '%B %d, %Y' 74# today_fmt = '%B %d, %Y'
80 75
81# List of patterns, relative to source directory, that match files and 76# List of patterns, relative to source directory, that match files and
82# directories to ignore when looking for source files. 77# directories to ignore when looking for source files.
@@ -84,27 +79,27 @@ exclude_patterns = ['_build']
84 79
85# The reST default role (used for this markup: `text`) to use for all 80# The reST default role (used for this markup: `text`) to use for all
86# documents. 81# documents.
87#default_role = None 82# default_role = None
88 83
89# If true, '()' will be appended to :func: etc. cross-reference text. 84# If true, '()' will be appended to :func: etc. cross-reference text.
90#add_function_parentheses = True 85# add_function_parentheses = True
91 86
92# If true, the current module name will be prepended to all description 87# If true, the current module name will be prepended to all description
93# unit titles (such as .. function::). 88# unit titles (such as .. function::).
94#add_module_names = True 89# add_module_names = True
95 90
96# If true, sectionauthor and moduleauthor directives will be shown in the 91# If true, sectionauthor and moduleauthor directives will be shown in the
97# output. They are ignored by default. 92# output. They are ignored by default.
98#show_authors = False 93# show_authors = False
99 94
100# The name of the Pygments (syntax highlighting) style to use. 95# The name of the Pygments (syntax highlighting) style to use.
101pygments_style = 'sphinx' 96pygments_style = 'sphinx'
102 97
103# A list of ignored prefixes for module index sorting. 98# A list of ignored prefixes for module index sorting.
104#modindex_common_prefix = [] 99# modindex_common_prefix = []
105 100
106# If true, keep warnings as "system message" paragraphs in the built documents. 101# If true, keep warnings as "system message" paragraphs in the built documents.
107#keep_warnings = False 102# keep_warnings = False
108 103
109# If true, `todo` and `todoList` produce output, else they produce nothing. 104# If true, `todo` and `todoList` produce output, else they produce nothing.
110todo_include_todos = False 105todo_include_todos = False
@@ -119,26 +114,26 @@ html_theme = 'sphinx_rtd_theme'
119# Theme options are theme-specific and customize the look and feel of a theme 114# Theme options are theme-specific and customize the look and feel of a theme
120# further. For a list of options available for each theme, see the 115# further. For a list of options available for each theme, see the
121# documentation. 116# documentation.
122#html_theme_options = {} 117# html_theme_options = {}
123 118
124# Add any paths that contain custom themes here, relative to this directory. 119# Add any paths that contain custom themes here, relative to this directory.
125#html_theme_path = [] 120# html_theme_path = []
126 121
127# The name for this set of Sphinx documents. If None, it defaults to 122# The name for this set of Sphinx documents. If None, it defaults to
128# "<project> v<release> documentation". 123# "<project> v<release> documentation".
129#html_title = None 124# html_title = None
130 125
131# A shorter title for the navigation bar. Default is the same as html_title. 126# A shorter title for the navigation bar. Default is the same as html_title.
132#html_short_title = None 127# html_short_title = None
133 128
134# The name of an image file (relative to this directory) to place at the top 129# The name of an image file (relative to this directory) to place at the top
135# of the sidebar. 130# of the sidebar.
136#html_logo = None 131# html_logo = None
137 132
138# The name of an image file (within the static path) to use as favicon of the 133# The name of an image file (within the static path) to use as favicon of the
139# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 134# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
140# pixels large. 135# pixels large.
141#html_favicon = None 136# html_favicon = None
142 137
143# Add any paths that contain custom static files (such as style sheets) here, 138# Add any paths that contain custom static files (such as style sheets) here,
144# relative to this directory. They are copied after the builtin static files, 139# relative to this directory. They are copied after the builtin static files,
@@ -148,62 +143,62 @@ html_static_path = ['_static']
148# Add any extra paths that contain custom files (such as robots.txt or 143# Add any extra paths that contain custom files (such as robots.txt or
149# .htaccess) here, relative to this directory. These files are copied 144# .htaccess) here, relative to this directory. These files are copied
150# directly to the root of the documentation. 145# directly to the root of the documentation.
151#html_extra_path = [] 146# html_extra_path = []
152 147
153# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 148# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
154# using the given strftime format. 149# using the given strftime format.
155#html_last_updated_fmt = '%b %d, %Y' 150# html_last_updated_fmt = '%b %d, %Y'
156 151
157# If true, SmartyPants will be used to convert quotes and dashes to 152# If true, SmartyPants will be used to convert quotes and dashes to
158# typographically correct entities. 153# typographically correct entities.
159#html_use_smartypants = True 154# html_use_smartypants = True
160 155
161# Custom sidebar templates, maps document names to template names. 156# Custom sidebar templates, maps document names to template names.
162#html_sidebars = {} 157# html_sidebars = {}
163 158
164# Additional templates that should be rendered to pages, maps page names to 159# Additional templates that should be rendered to pages, maps page names to
165# template names. 160# template names.
166#html_additional_pages = {} 161# html_additional_pages = {}
167 162
168# If false, no module index is generated. 163# If false, no module index is generated.
169#html_domain_indices = True 164# html_domain_indices = True
170 165
171# If false, no index is generated. 166# If false, no index is generated.
172#html_use_index = True 167# html_use_index = True
173 168
174# If true, the index is split into individual pages for each letter. 169# If true, the index is split into individual pages for each letter.
175#html_split_index = False 170# html_split_index = False
176 171
177# If true, links to the reST sources are added to the pages. 172# If true, links to the reST sources are added to the pages.
178#html_show_sourcelink = True 173# html_show_sourcelink = True
179 174
180# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 175# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
181#html_show_sphinx = True 176# html_show_sphinx = True
182 177
183# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 178# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
184#html_show_copyright = True 179# html_show_copyright = True
185 180
186# If true, an OpenSearch description file will be output, and all pages will 181# If true, an OpenSearch description file will be output, and all pages will
187# contain a <link> tag referring to it. The value of this option must be the 182# contain a <link> tag referring to it. The value of this option must be the
188# base URL from which the finished HTML is served. 183# base URL from which the finished HTML is served.
189#html_use_opensearch = '' 184# html_use_opensearch = ''
190 185
191# This is the file name suffix for HTML files (e.g. ".xhtml"). 186# This is the file name suffix for HTML files (e.g. ".xhtml").
192#html_file_suffix = None 187# html_file_suffix = None
193 188
194# Language to be used for generating the HTML full-text search index. 189# Language to be used for generating the HTML full-text search index.
195# Sphinx supports the following languages: 190# Sphinx supports the following languages:
196# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 191# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
197# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' 192# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
198#html_search_language = 'en' 193# html_search_language = 'en'
199 194
200# A dictionary with options for the search language support, empty by default. 195# A dictionary with options for the search language support, empty by default.
201# Now only 'ja' uses this config value 196# Now only 'ja' uses this config value
202#html_search_options = {'type': 'default'} 197# html_search_options = {'type': 'default'}
203 198
204# The name of a javascript file (relative to the configuration directory) that 199# The name of a javascript file (relative to the configuration directory) that
205# implements a search results scorer. If empty, the default will be used. 200# implements a search results scorer. If empty, the default will be used.
206#html_search_scorer = 'scorer.js' 201# html_search_scorer = 'scorer.js'
207 202
208# Output file base name for HTML help builder. 203# Output file base name for HTML help builder.
209htmlhelp_basename = 'EventMQdoc' 204htmlhelp_basename = 'EventMQdoc'
@@ -211,17 +206,17 @@ htmlhelp_basename = 'EventMQdoc'
211# -- Options for LaTeX output --------------------------------------------- 206# -- Options for LaTeX output ---------------------------------------------
212 207
213latex_elements = { 208latex_elements = {
214# The paper size ('letterpaper' or 'a4paper'). 209 # The paper size ('letterpaper' or 'a4paper').
215#'papersize': 'letterpaper', 210 # 'papersize': 'letterpaper',
216 211
217# The font size ('10pt', '11pt' or '12pt'). 212 # The font size ('10pt', '11pt' or '12pt').
218#'pointsize': '10pt', 213 # 'pointsize': '10pt',
219 214
220# Additional stuff for the LaTeX preamble. 215 # Additional stuff for the LaTeX preamble.
221#'preamble': '', 216 # 'preamble': '',
222 217
223# Latex figure (float) alignment 218 # Latex figure (float) alignment
224#'figure_align': 'htbp', 219 # 'figure_align': 'htbp',
225} 220}
226 221
227# Grouping the document tree into LaTeX files. List of tuples 222# Grouping the document tree into LaTeX files. List of tuples
@@ -234,23 +229,23 @@ latex_documents = [
234 229
235# The name of an image file (relative to this directory) to place at the top of 230# The name of an image file (relative to this directory) to place at the top of
236# the title page. 231# the title page.
237#latex_logo = None 232# latex_logo = None
238 233
239# For "manual" documents, if this is true, then toplevel headings are parts, 234# For "manual" documents, if this is true, then toplevel headings are parts,
240# not chapters. 235# not chapters.
241#latex_use_parts = False 236# latex_use_parts = False
242 237
243# If true, show page references after internal links. 238# If true, show page references after internal links.
244#latex_show_pagerefs = False 239# latex_show_pagerefs = False
245 240
246# If true, show URL addresses after external links. 241# If true, show URL addresses after external links.
247#latex_show_urls = False 242# latex_show_urls = False
248 243
249# Documents to append as an appendix to all manuals. 244# Documents to append as an appendix to all manuals.
250#latex_appendices = [] 245# latex_appendices = []
251 246
252# If false, no module index is generated. 247# If false, no module index is generated.
253#latex_domain_indices = True 248# latex_domain_indices = True
254 249
255 250
256# -- Options for manual page output --------------------------------------- 251# -- Options for manual page output ---------------------------------------
@@ -263,7 +258,7 @@ man_pages = [
263] 258]
264 259
265# If true, show URL addresses after external links. 260# If true, show URL addresses after external links.
266#man_show_urls = False 261# man_show_urls = False
267 262
268 263
269# -- Options for Texinfo output ------------------------------------------- 264# -- Options for Texinfo output -------------------------------------------
@@ -278,16 +273,16 @@ texinfo_documents = [
278] 273]
279 274
280# Documents to append as an appendix to all manuals. 275# Documents to append as an appendix to all manuals.
281#texinfo_appendices = [] 276# texinfo_appendices = []
282 277
283# If false, no module index is generated. 278# If false, no module index is generated.
284#texinfo_domain_indices = True 279# texinfo_domain_indices = True
285 280
286# How to display URL addresses: 'footnote', 'no', or 'inline'. 281# How to display URL addresses: 'footnote', 'no', or 'inline'.
287#texinfo_show_urls = 'footnote' 282# texinfo_show_urls = 'footnote'
288 283
289# If true, do not generate a @detailmenu in the "Top" node's menu. 284# If true, do not generate a @detailmenu in the "Top" node's menu.
290#texinfo_no_detailmenu = False 285# texinfo_no_detailmenu = False
291 286
292 287
293# Example configuration for intersphinx: refer to the Python standard library. 288# Example configuration for intersphinx: refer to the Python standard library.
diff --git a/eventmq/client/jobs.py b/eventmq/client/jobs.py
index 0278ccd..2f4f784 100644
--- a/eventmq/client/jobs.py
+++ b/eventmq/client/jobs.py
@@ -19,9 +19,9 @@
19import logging 19import logging
20import os 20import os
21 21
22from . import messages
22from ..constants import ENV_BROKER_ADDR 23from ..constants import ENV_BROKER_ADDR
23from ..sender import Sender 24from ..sender import Sender
24from . import messages
25 25
26logger = logging.getLogger(__name__) 26logger = logging.getLogger(__name__)
27 27
diff --git a/eventmq/client/messages.py b/eventmq/client/messages.py
index 02ef2d9..1963e6e 100644
--- a/eventmq/client/messages.py
+++ b/eventmq/client/messages.py
@@ -16,13 +16,14 @@
16:mod:`messages` -- Client Messaging 16:mod:`messages` -- Client Messaging
17=================================== 17===================================
18""" 18"""
19import logging
20from json import dumps as serialize 19from json import dumps as serialize
20import logging
21
21from past.builtins import basestring 22from past.builtins import basestring
22 23
23from .. import conf 24from .. import conf
24from ..utils.messages import send_emqp_message
25from ..utils.functions import name_from_callable, split_callable_name 25from ..utils.functions import name_from_callable, split_callable_name
26from ..utils.messages import send_emqp_message
26 27
27logger = logging.getLogger(__name__) 28logger = logging.getLogger(__name__)
28 29
diff --git a/eventmq/conf.py b/eventmq/conf.py
index 6a0b3a4..cec0249 100644
--- a/eventmq/conf.py
+++ b/eventmq/conf.py
@@ -86,6 +86,6 @@ RQ_PORT = 6379
86RQ_DB = 0 86RQ_DB = 0
87RQ_PASSWORD = '' 87RQ_PASSWORD = ''
88 88
89MAX_JOB_COUNT=1024 89MAX_JOB_COUNT = 1024
90 90
91# }}} 91# }}}
diff --git a/eventmq/jobmanager.py b/eventmq/jobmanager.py
index ed48e0d..9d0afbc 100644
--- a/eventmq/jobmanager.py
+++ b/eventmq/jobmanager.py
@@ -17,25 +17,25 @@
17================================ 17================================
18Ensures things about jobs and spawns the actual tasks 18Ensures things about jobs and spawns the actual tasks
19""" 19"""
20import sys 20from json import loads as deserializer
21import logging 21import logging
22from multiprocessing import Queue as mp_queue
22import signal 23import signal
23import zmq 24import sys
24 25
25from json import loads as deserializer 26import zmq
26 27
28from eventmq.log import setup_logger
27from . import conf 29from . import conf
28from .constants import KBYE 30from .constants import KBYE
29from .poller import Poller, POLLIN 31from .poller import Poller, POLLIN
30from .sender import Sender 32from .sender import Sender
31from .utils.classes import EMQPService, HeartbeatMixin 33from .utils.classes import EMQPService, HeartbeatMixin
32from .utils.settings import import_settings
33from .utils.devices import generate_device_name 34from .utils.devices import generate_device_name
34from .utils.messages import send_emqp_message as sendmsg
35from .utils.functions import get_timeout_from_headers 35from .utils.functions import get_timeout_from_headers
36from .utils.messages import send_emqp_message as sendmsg
37from .utils.settings import import_settings
36from .worker import MultiprocessWorker as Worker 38from .worker import MultiprocessWorker as Worker
37from eventmq.log import setup_logger
38from multiprocessing import Queue as mp_queue
39 39
40if sys.version[0] == '2': 40if sys.version[0] == '2':
41 import Queue 41 import Queue
diff --git a/eventmq/log.py b/eventmq/log.py
index 325aa16..2c5919d 100644
--- a/eventmq/log.py
+++ b/eventmq/log.py
@@ -53,8 +53,8 @@ def setup_logger(base_name, formatter=FORMAT_STANDARD,
53 logger.setLevel(logging.DEBUG) 53 logger.setLevel(logging.DEBUG)
54 54
55 # remove handlers we don't want 55 # remove handlers we don't want
56 #for h in logger.handlers: 56 # for h in logger.handlers:
57 # logger.removeHandler(h) 57 # logger.removeHandler(h)
58 58
59 if handler == handlers.PUBLISH_HANDLER: 59 if handler == handlers.PUBLISH_HANDLER:
60 _handler_sock = zmq.Context.instance().socket(zmq.PUB) 60 _handler_sock = zmq.Context.instance().socket(zmq.PUB)
diff --git a/eventmq/pub.py b/eventmq/pub.py
index 2a27c40..3918580 100644
--- a/eventmq/pub.py
+++ b/eventmq/pub.py
@@ -17,17 +17,13 @@
17======================= 17=======================
18Publishes messages to subscribers 18Publishes messages to subscribers
19""" 19"""
20import zmq
21
22import logging 20import logging
23 21
24from . import conf, receiver, poller, publisher 22from eventmq.log import setup_logger
25 23
24from . import conf, poller, publisher, receiver
25from .constants import STATUS
26from .utils.classes import HeartbeatMixin 26from .utils.classes import HeartbeatMixin
27from .utils.timeutils import monotonic, timestamp
28from .constants import (STATUS, CLIENT_TYPE, PROTOCOL_VERSION, KBYE,
29 DISCONNECT)
30from eventmq.log import setup_logger
31from .utils.settings import import_settings 27from .utils.settings import import_settings
32 28
33logger = logging.getLogger(__name__) 29logger = logging.getLogger(__name__)
diff --git a/eventmq/publisher.py b/eventmq/publisher.py
index 23eb04e..2e77bcd 100644
--- a/eventmq/publisher.py
+++ b/eventmq/publisher.py
@@ -17,11 +17,11 @@
17======================= 17=======================
18Publishes messages to subscribers 18Publishes messages to subscribers
19""" 19"""
20import zmq
21import logging 20import logging
22 21
23from . import constants 22import zmq
24 23
24from . import constants
25from .utils.devices import generate_device_name 25from .utils.devices import generate_device_name
26 26
27logger = logging.getLogger(__name__) 27logger = logging.getLogger(__name__)
diff --git a/eventmq/receiver.py b/eventmq/receiver.py
index 2d28594..4450e2e 100644
--- a/eventmq/receiver.py
+++ b/eventmq/receiver.py
@@ -18,6 +18,7 @@
18The receiver is responsible for receiveing messages 18The receiver is responsible for receiveing messages
19""" 19"""
20import logging 20import logging
21
21import zmq 22import zmq
22 23
23from . import constants 24from . import constants
diff --git a/eventmq/router.py b/eventmq/router.py
index 71f40d3..2943e3c 100644
--- a/eventmq/router.py
+++ b/eventmq/router.py
@@ -22,22 +22,22 @@ import json # deserialize queues in on_inform. should be refactored
22import logging 22import logging
23import signal 23import signal
24 24
25from eventmq.log import setup_logger
25from . import conf, constants, exceptions, poller, receiver 26from . import conf, constants, exceptions, poller, receiver
26from .constants import ( 27from .constants import (
27 STATUS, CLIENT_TYPE, PROTOCOL_VERSION, KBYE, DISCONNECT, 28 CLIENT_TYPE, DISCONNECT, KBYE, PROTOCOL_VERSION, ROUTER_SHOW_SCHEDULERS,
28 ROUTER_SHOW_SCHEDULERS, ROUTER_SHOW_WORKERS 29 ROUTER_SHOW_WORKERS, STATUS
29) 30)
31from .utils import tuplify
30from .utils.classes import EMQdeque, HeartbeatMixin 32from .utils.classes import EMQdeque, HeartbeatMixin
33from .utils.devices import generate_device_name
31from .utils.messages import ( 34from .utils.messages import (
32 send_emqp_router_message as sendmsg,
33 fwd_emqp_router_message as fwdmsg, 35 fwd_emqp_router_message as fwdmsg,
34 parse_router_message 36 parse_router_message,
37 send_emqp_router_message as sendmsg,
35) 38)
36from .utils import tuplify
37from .utils.settings import import_settings 39from .utils.settings import import_settings
38from .utils.devices import generate_device_name
39from .utils.timeutils import monotonic, timestamp 40from .utils.timeutils import monotonic, timestamp
40from eventmq.log import setup_logger
41 41
42 42
43logger = logging.getLogger(__name__) 43logger = logging.getLogger(__name__)
@@ -111,12 +111,12 @@ class Router(HeartbeatMixin):
111 self.schedulers = {} 111 self.schedulers = {}
112 112
113 #: Latency tracking dictionary 113 #: Latency tracking dictionary
114 #: Key: msgid of message each REQUEST received and forwarded to a worker 114 #: Key: msgid of msg each REQUEST received and forwarded to a worker
115 #: Value: (timestamp, queue_name) 115 #: Value: (timestamp, queue_name)
116 self.job_latencies = {} 116 self.job_latencies = {}
117 117
118 #: Excecuted function tracking dictionary 118 #: Excecuted function tracking dictionary
119 #: Key: msgid of message each REQUEST received and forwarded to a worker 119 #: Key: msgid of msg each REQUEST received and forwarded to a worker
120 #: Value: (function_name, queue_name) 120 #: Value: (function_name, queue_name)
121 self.executed_functions = {} 121 self.executed_functions = {}
122 122
@@ -186,7 +186,8 @@ class Router(HeartbeatMixin):
186 if len(msg) > 4: 186 if len(msg) > 4:
187 if msg[3] == DISCONNECT: 187 if msg[3] == DISCONNECT:
188 logger.info('Received DISCONNECT from administrator') 188 logger.info('Received DISCONNECT from administrator')
189 self.send_ack(self.administrative_socket, msg[0], msg[4]) 189 self.send_ack(
190 self.administrative_socket, msg[0], msg[4])
190 self.on_disconnect(msg[4], msg) 191 self.on_disconnect(msg[4], msg)
191 elif msg[3] == 'STATUS': 192 elif msg[3] == 'STATUS':
192 sendmsg(self.administrative_socket, msg[0], 'REPLY', 193 sendmsg(self.administrative_socket, msg[0], 'REPLY',
@@ -334,11 +335,13 @@ class Router(HeartbeatMixin):
334 sender, msgid, orig_msgid)) 335 sender, msgid, orig_msgid))
335 336
336 if orig_msgid in self.job_latencies: 337 if orig_msgid in self.job_latencies:
338 elapsed_secs = (monotonic()
339 - self.job_latencies[orig_msgid][0]) * 1000.0
337 logger.info("Completed {queue} job with msgid: {msgid} in " 340 logger.info("Completed {queue} job with msgid: {msgid} in "
338 "{time:.2f}ms".\ 341 "{time:.2f}ms".format(
339 format(queue=self.job_latencies[orig_msgid][1], 342 queue=self.job_latencies[orig_msgid][1],
340 msgid=orig_msgid, 343 msgid=orig_msgid,
341 time=(monotonic()-self.job_latencies[orig_msgid][0])*1000.0)) 344 time=elapsed_secs))
342 del self.job_latencies[orig_msgid] 345 del self.job_latencies[orig_msgid]
343 346
344 def on_disconnect(self, msgid, msg): 347 def on_disconnect(self, msgid, msg):
@@ -400,7 +403,8 @@ class Router(HeartbeatMixin):
400 fwdmsg(self.outgoing, sender, msg) 403 fwdmsg(self.outgoing, sender, msg)
401 self.waiting_messages[queue_name].popleft() 404 self.waiting_messages[queue_name].popleft()
402 except exceptions.PeerGoneAwayError: 405 except exceptions.PeerGoneAwayError:
403 # Cleanup a worker that cannot be contacted, leaving the message in queue 406 # Cleanup a workerg that cannot be contacted, leaving the
407 # message in queue
404 self.workers[sender]['hb'] = 0 408 self.workers[sender]['hb'] = 0
405 self.clean_up_dead_workers() 409 self.clean_up_dead_workers()
406 410
@@ -460,8 +464,8 @@ class Router(HeartbeatMixin):
460 # Set queue limit to be 75% of total memory with ~100 byte 464 # Set queue limit to be 75% of total memory with ~100 byte
461 # messages 465 # messages
462 limit = int((total_mem / 100) * 0.75) 466 limit = int((total_mem / 100) * 0.75)
463 self.waiting_messages[queue_name] = \ 467 self.waiting_messages[queue_name] = EMQdeque(
464 EMQdeque(full=limit, on_full=router_on_full) 468 full=limit, on_full=router_on_full)
465 else: 469 else:
466 self.waiting_messages[queue_name] = \ 470 self.waiting_messages[queue_name] = \
467 EMQdeque(full=conf.HWM, 471 EMQdeque(full=conf.HWM,
@@ -922,4 +926,4 @@ def router_on_full():
922 926
923# Entry point for pip console scripts 927# Entry point for pip console scripts
924def router_main(): 928def router_main():
925 r = Router() 929 Router()
diff --git a/eventmq/scheduler.py b/eventmq/scheduler.py
index ab542cc..7f19d84 100644
--- a/eventmq/scheduler.py
+++ b/eventmq/scheduler.py
@@ -18,26 +18,26 @@
18Handles cron and other scheduled tasks 18Handles cron and other scheduled tasks
19""" 19"""
20import json 20import json
21from json import dumps as serialize
22from json import loads as deserialize
21import logging 23import logging
22import redis
23 24
24from croniter import croniter 25from croniter import croniter
26import redis
25from six import next 27from six import next
26 28
29from eventmq.log import setup_logger
30
27from . import conf, constants 31from . import conf, constants
32from .client.messages import send_request
28from .constants import KBYE 33from .constants import KBYE
29from .sender import Sender
30from .poller import Poller, POLLIN 34from .poller import Poller, POLLIN
35from .sender import Sender
31from .utils.classes import EMQPService, HeartbeatMixin 36from .utils.classes import EMQPService, HeartbeatMixin
32from json import loads as deserialize
33from json import dumps as serialize
34from .utils.messages import send_emqp_message as sendmsg 37from .utils.messages import send_emqp_message as sendmsg
35from .utils.settings import import_settings 38from .utils.settings import import_settings
36from .utils.timeutils import IntervalIter 39from .utils.timeutils import IntervalIter, monotonic, seconds_until, timestamp
37from .utils.timeutils import seconds_until, timestamp, monotonic
38from .client.messages import send_request
39 40
40from eventmq.log import setup_logger
41 41
42logger = logging.getLogger(__name__) 42logger = logging.getLogger(__name__)
43CRON_CALLER_ID = -1 43CRON_CALLER_ID = -1
@@ -463,4 +463,4 @@ def scheduler_main():
463 463
464 464
465def test_job(): 465def test_job():
466 print("hello!") 466 print("hello!") # noqa
diff --git a/eventmq/subscriber.py b/eventmq/subscriber.py
index 5976856..f585572 100644
--- a/eventmq/subscriber.py
+++ b/eventmq/subscriber.py
@@ -2,7 +2,7 @@
2derp subscriber 2derp subscriber
3""" 3"""
4import zmq 4import zmq
5import sys 5
6 6
7if __name__ == "__main__": 7if __name__ == "__main__":
8 sockets = [] 8 sockets = []
@@ -18,4 +18,4 @@ if __name__ == "__main__":
18 # block until something comes in. normally you'd do something with 18 # block until something comes in. normally you'd do something with
19 # this in another thread or something 19 # this in another thread or something
20 for s in sockets: 20 for s in sockets:
21 print s.recv_multipart() 21 print s.recv_multipart() # noqa
diff --git a/eventmq/tests/test_client_jobs.py b/eventmq/tests/test_client_jobs.py
index 45e6a90..6a7d054 100644
--- a/eventmq/tests/test_client_jobs.py
+++ b/eventmq/tests/test_client_jobs.py
@@ -19,6 +19,7 @@ from testfixtures import LogCapture
19 19
20from ..client import jobs 20from ..client import jobs
21 21
22
22class TestCase(unittest.TestCase): 23class TestCase(unittest.TestCase):
23 BROKER_ADDR = 'tcp://127.0.0.1:3748' 24 BROKER_ADDR = 'tcp://127.0.0.1:3748'
24 25
diff --git a/eventmq/tests/test_jobmanager.py b/eventmq/tests/test_jobmanager.py
index d36a7db..d0497bc 100644
--- a/eventmq/tests/test_jobmanager.py
+++ b/eventmq/tests/test_jobmanager.py
@@ -89,7 +89,9 @@ class TestCase(unittest.TestCase):
89 def test_on_request_with_timeout_and_reply(self): 89 def test_on_request_with_timeout_and_reply(self):
90 timeout = 3 90 timeout = 3
91 _msgid = 'aaa0j8-ac40jf0-04tjv' 91 _msgid = 'aaa0j8-ac40jf0-04tjv'
92 _msg = ['a', 'timeout:{},reply-requested'.format(timeout), '["run", {"a": 1}]'] 92 _msg = ['a',
93 'timeout:{},reply-requested'.format(timeout),
94 '["run", {"a": 1}]']
93 95
94 jm = jobmanager.JobManager() 96 jm = jobmanager.JobManager()
95 97
diff --git a/eventmq/tests/test_receiver.py b/eventmq/tests/test_receiver.py
index 90e1d3b..4ee7170 100644
--- a/eventmq/tests/test_receiver.py
+++ b/eventmq/tests/test_receiver.py
@@ -15,12 +15,8 @@
15import unittest 15import unittest
16 16
17import zmq 17import zmq
18import signal
19import os
20 18
21from .. import router 19from .. import receiver, router, sender
22from .. import receiver
23from .. import sender
24 20
25 21
26class TestCase(unittest.TestCase): 22class TestCase(unittest.TestCase):
diff --git a/eventmq/tests/test_router.py b/eventmq/tests/test_router.py
index 0832a7d..fdb02d0 100644
--- a/eventmq/tests/test_router.py
+++ b/eventmq/tests/test_router.py
@@ -14,7 +14,6 @@
14# along with eventmq. If not, see <http://www.gnu.org/licenses/>. 14# along with eventmq. If not, see <http://www.gnu.org/licenses/>.
15import json 15import json
16import unittest 16import unittest
17import uuid
18 17
19from freezegun import freeze_time 18from freezegun import freeze_time
20import mock 19import mock
@@ -344,7 +343,7 @@ class TestCase(unittest.TestCase):
344 } 343 }
345 } 344 }
346 self.router.queues = { 345 self.router.queues = {
347 queue: [(10, worker_id),] 346 queue: [(10, worker_id), ]
348 } 347 }
349 348
350 # Router accepts job for 1 available slot 349 # Router accepts job for 1 available slot
@@ -715,7 +714,7 @@ class TestCase(unittest.TestCase):
715 } 714 }
716 715
717 self.router.process_worker_message((w2, '', constants.PROTOCOL_VERSION, 716 self.router.process_worker_message((w2, '', constants.PROTOCOL_VERSION,
718 command, msgid) + msg) 717 command, msgid) + msg)
719 self.assertNotIn( 718 self.assertNotIn(
720 w2, self.router.queues[queue1_id], 719 w2, self.router.queues[queue1_id],
721 "Worker not removed from {}".format(queue1_id)) 720 "Worker not removed from {}".format(queue1_id))
@@ -780,9 +779,9 @@ class TestCase(unittest.TestCase):
780 'job_latencies': self.router.job_latencies, 779 'job_latencies': self.router.job_latencies,
781 'executed_functions': self.router.executed_functions, 780 'executed_functions': self.router.executed_functions,
782 'waiting_message_counts': [ 781 'waiting_message_counts': [
783 '{}: {}'.format(q, 782 '{}: {}'.format(
784 len(self.router.waiting_messages[q])) 783 q,
785 for q in self.router.waiting_messages] 784 len(self.router.waiting_messages[q])) for q in self.router.waiting_messages] # noqa
786 })), 785 })),
787 json.loads(self.router.get_status())) 786 json.loads(self.router.get_status()))
788 787
diff --git a/eventmq/tests/test_scheduler.py b/eventmq/tests/test_scheduler.py
index df3779f..eb52dec 100644
--- a/eventmq/tests/test_scheduler.py
+++ b/eventmq/tests/test_scheduler.py
@@ -12,12 +12,9 @@
12# 12#
13# You should have received a copy of the GNU Lesser General Public License 13# You should have received a copy of the GNU Lesser General Public License
14# along with eventmq. If not, see <http://www.gnu.org/licenses/>. 14# along with eventmq. If not, see <http://www.gnu.org/licenses/>.
15import time
16import unittest 15import unittest
17 16
18import mock 17from .. import constants, scheduler
19
20from .. import conf, constants, scheduler
21 18
22ADDR = 'inproc://pour_the_rice_in_the_thing' 19ADDR = 'inproc://pour_the_rice_in_the_thing'
23 20
diff --git a/eventmq/tests/test_sender.py b/eventmq/tests/test_sender.py
index 8178e30..b2570a3 100644
--- a/eventmq/tests/test_sender.py
+++ b/eventmq/tests/test_sender.py
@@ -15,8 +15,6 @@
15import unittest 15import unittest
16 16
17import zmq 17import zmq
18import signal
19import os
20 18
21from .. import sender 19from .. import sender
22 20
diff --git a/eventmq/tests/test_utils.py b/eventmq/tests/test_utils.py
index 478a997..03da18a 100644
--- a/eventmq/tests/test_utils.py
+++ b/eventmq/tests/test_utils.py
@@ -22,9 +22,7 @@ import mock
22 22
23from .. import constants 23from .. import constants
24from .. import exceptions 24from .. import exceptions
25from ..utils import messages 25from ..utils import classes, messages, settings
26from ..utils import classes
27from ..utils import settings
28 26
29 27
30class SettingsTestCase(unittest.TestCase): 28class SettingsTestCase(unittest.TestCase):
diff --git a/eventmq/tests/test_utils_encoding.py b/eventmq/tests/test_utils_encoding.py
index bcc0be2..a02ce96 100644
--- a/eventmq/tests/test_utils_encoding.py
+++ b/eventmq/tests/test_utils_encoding.py
@@ -37,6 +37,7 @@ class TestCase(unittest.TestCase):
37 (b'one', 1, (b'two', 2, 37 (b'one', 1, (b'two', 2,
38 [b'three', 3], 38 [b'three', 3],
39 {'asdf': 90, 'bp': b'adam'}))) 39 {'asdf': 90, 'bp': b'adam'})))
40
40 def test_encodify_dict(self): 41 def test_encodify_dict(self):
41 test_dict = { 42 test_dict = {
42 'key1': 1, 43 'key1': 1,
diff --git a/eventmq/tests/utils.py b/eventmq/tests/utils.py
index 4bbbb51..23f34c0 100644
--- a/eventmq/tests/utils.py
+++ b/eventmq/tests/utils.py
@@ -12,13 +12,12 @@
12# 12#
13# You should have received a copy of the GNU General Public License 13# You should have received a copy of the GNU General Public License
14# along with eventmq. If not, see <http://www.gnu.org/licenses/>. 14# along with eventmq. If not, see <http://www.gnu.org/licenses/>.
15import time
16import uuid 15import uuid
17 16
18import zmq 17import zmq
19 18
20from .. import conf, constants 19from .. import conf, constants
21from ..utils.classes import ZMQSendMixin, ZMQReceiveMixin 20from ..utils.classes import ZMQReceiveMixin, ZMQSendMixin
22from ..utils.devices import generate_device_name 21from ..utils.devices import generate_device_name
23 22
24 23
diff --git a/eventmq/utils/classes.py b/eventmq/utils/classes.py
index 7233498..d1ca275 100644
--- a/eventmq/utils/classes.py
+++ b/eventmq/utils/classes.py
@@ -17,12 +17,12 @@
17================================= 17=================================
18Defines some classes to use when implementing ZMQ devices 18Defines some classes to use when implementing ZMQ devices
19""" 19"""
20from collections import deque
20import json 21import json
21import logging 22import logging
22 23
23import zmq.error 24import zmq.error
24 25
25from collections import deque
26from .. import conf, constants, exceptions, poller, utils 26from .. import conf, constants, exceptions, poller, utils
27from ..utils.encoding import encodify 27from ..utils.encoding import encodify
28from ..utils.messages import send_emqp_message as sendmsg 28from ..utils.messages import send_emqp_message as sendmsg
diff --git a/eventmq/utils/encoding.py b/eventmq/utils/encoding.py
index 1b7c936..d45624e 100644
--- a/eventmq/utils/encoding.py
+++ b/eventmq/utils/encoding.py
@@ -12,8 +12,6 @@
12# 12#
13# You should have received a copy of the GNU Lesser General Public License 13# You should have received a copy of the GNU Lesser General Public License
14# along with eventmq. If not, see <http://www.gnu.org/licenses/>. 14# along with eventmq. If not, see <http://www.gnu.org/licenses/>.
15from copy import copy
16from codecs import encode
17from past.builtins import basestring 15from past.builtins import basestring
18 16
19from .. import conf 17from .. import conf
diff --git a/eventmq/utils/functions.py b/eventmq/utils/functions.py
index f0e6366..0d64725 100644
--- a/eventmq/utils/functions.py
+++ b/eventmq/utils/functions.py
@@ -1,7 +1,7 @@
1import json
2import hashlib 1import hashlib
3import importlib 2import importlib
4import inspect 3import inspect
4import json
5 5
6from .. import log 6from .. import log
7from ..exceptions import CallableFromPathError 7from ..exceptions import CallableFromPathError
diff --git a/eventmq/utils/messages.py b/eventmq/utils/messages.py
index 32bf2ce..02ac129 100644
--- a/eventmq/utils/messages.py
+++ b/eventmq/utils/messages.py
@@ -18,8 +18,8 @@
18""" 18"""
19import logging 19import logging
20 20
21from .. import conf, constants, exceptions
22from . import random_characters 21from . import random_characters
22from .. import conf, constants, exceptions
23 23
24logger = logging.getLogger(__name__) 24logger = logging.getLogger(__name__)
25 25
diff --git a/eventmq/utils/timeutils.py b/eventmq/utils/timeutils.py
index 0f777a6..b33e18d 100644
--- a/eventmq/utils/timeutils.py
+++ b/eventmq/utils/timeutils.py
@@ -17,7 +17,7 @@
17================================= 17=================================
18""" 18"""
19try: 19try:
20 from time import monotonic as _monotonic # Python3 20 from time import monotonic as _monotonic # Python3
21except ImportError: 21except ImportError:
22 from monotonic import monotonic as _monotonic 22 from monotonic import monotonic as _monotonic
23from time import time as _time 23from time import time as _time
diff --git a/eventmq/worker.py b/eventmq/worker.py
index 29814f4..7729120 100644
--- a/eventmq/worker.py
+++ b/eventmq/worker.py
@@ -18,12 +18,12 @@
18Defines different short-lived workers that execute jobs 18Defines different short-lived workers that execute jobs
19""" 19"""
20from importlib import import_module 20from importlib import import_module
21import logging
21from multiprocessing import Process 22from multiprocessing import Process
23import os
22from threading import Thread 24from threading import Thread
23from . import conf
24 25
25import logging 26from . import conf
26import os
27 27
28logger = logging.getLogger(__name__) 28logger = logging.getLogger(__name__)
29 29
diff --git a/requirements_.txt b/requirements_.txt
deleted file mode 100644
index dd252bc..0000000
--- a/requirements_.txt
+++ /dev/null
@@ -1,19 +0,0 @@
1pyzmq==15.4.0
2six==1.10.0
3monotonic==0.4 # A clock who's time is not changed. used for scheduling
4croniter==0.3.10
5redis==2.10.3
6future==0.15.2
7psutil==5.0.0
8
9# Documentation
10sphinxcontrib-napoleon==0.4.3
11Sphinx==1.3.1 # must come after napoleon to get the latest version
12
13# Testing
14nose==1.3.6
15coverage==4.0.3
16testfixtures==4.7.0 # To test that logging exists
17mock==1.3.0
18freezegun==0.3.7
19tl.testing==0.5
diff --git a/setup.py b/setup.py
index 31c35c7..115e102 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ EventMQ setup.py file for distribution
3 3
4""" 4"""
5 5
6from setuptools import setup, find_packages 6from setuptools import find_packages, setup
7 7
8setup( 8setup(
9 name='eventmq', 9 name='eventmq',
@@ -18,6 +18,19 @@ setup(
18 'future==0.15.2', 18 'future==0.15.2',
19 'psutil==5.0.0', 19 'psutil==5.0.0',
20 'python-dateutil>=2.1,<3.0.0'], 20 'python-dateutil>=2.1,<3.0.0'],
21 extras_require={
22 'docs': ['Sphinx==1.5.2', ],
23 'testing': [
24 'flake8==3.2.1',
25 'flake8-import-order==0.11',
26 'flake8-print==2.0.2',
27 'nose',
28 'coverage==4.0.3',
29 'testfixtures==4.7.0',
30 'freezegun==0.3.7',
31 'tl.testing==0.5',
32 'mock==1.3.0'],
33 },
21 author='EventMQ Contributors', 34 author='EventMQ Contributors',
22 url='https://github.com/enderlabs/eventmq/', 35 url='https://github.com/enderlabs/eventmq/',
23 36
@@ -34,7 +47,7 @@ setup(
34 'Topic :: System :: Distributed Computing', 47 'Topic :: System :: Distributed Computing',
35 48
36 # Pick your license as you wish (should match "license" above) 49 # Pick your license as you wish (should match "license" above)
37 'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)', 50 'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)', # noqa
38 'Operating System :: OS Independent', 51 'Operating System :: OS Independent',
39 # Specify the Python versions you support here. In particular, ensure 52 # Specify the Python versions you support here. In particular, ensure
40 # that you indicate whether you support Python 2, Python 3 or both. 53 # that you indicate whether you support Python 2, Python 3 or both.