Commit Graph

183 Commits (3b63da670fe70d4272fcc2963d927a50322749b7)

Author SHA1 Message Date
David Wilson 3b63da670f Fix up another handful of LGTM errors. 5 years ago
David Wilson 57012e0f72 Add mitogen.core.now() and use it everywhere; closes #614. 5 years ago
David Wilson 93e8d5dfcc docs: fix Sphinx warnings, add LogHandler, more docstrings 5 years ago
Marc Hartmayer 2ed8395d6c master: fix TypeError
Add a guard for the case `path == None`.

This commit fixes

`TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType`
5 years ago
David Wilson a79d2bd50b docs: another round of docstring cleanups. 5 years ago
David Wilson 20532ea591 master: allow filtering forwarded logs using logging package functions.
Given a message sent on "ssh.foo" to "mypkg.mymod", instead of logging
it to "mitogen.ctx.ssh.foo" in the master process, with the message
prefixed with the original logger name, instead log it to
"mypkg.mymod.[ssh.foo]", permitting normal logging package filtering
features to work as they usually do.

This also helps tidy up logging output a little bit.
5 years ago
David Wilson feb1654305 docs: many more internals.rst tidyups 5 years ago
David Wilson 5298e87548 Split out and make readable more log messages across both packages 5 years ago
David Wilson 93342ba60c Normalize docstring formatting 5 years ago
David Wilson 93abbcaf7a [stream-refactor] fix crash in runner/forking_active.yml 5 years ago
David Wilson 8d1b01d8ef Refactor Stream, introduce quasi-asynchronous connect, much more
Split Stream into many, many classes

  * mitogen.parent.Connection: Handles connection setup logic only.
    * Maintain references to stdout and stderr streams.
    * Manages TimerList timer to cancel connection attempt after
      deadline
    * Blocking setup code replaced by async equivalents running on the
      broker

  * mitogen.parent.Options: Tracks connection-specific options. This
    keeps the connection class small, but more importantly, it is
    generic to the future desire to build and execute command lines
    without starting a full connection.

  * mitogen.core.Protocol: Handles program behaviour relating to events
    on a stream. Protocol performs no IO of its own, instead deferring
    it to Stream and Side. This makes testing much easier, and means
    libssh can reimplement Stream and Side to reuse MitogenProtocol

  * mitogen.core.MitogenProtocol: Guts of the old Mitogen stream
    implementtion

  * mitogen.core.BufferedWriter: Guts of the old Mitogen buffered
    transmit implementation, made generic

  * mitogen.core.DelineatedProtocol: Guts of the old IoLogger, knows how
    to split up input and pass it on to a
    on_line_received()/on_partial_line_received() callback.

  * mitogen.parent.BootstrapProtocol: Asynchronous equivalent of the old
    blocking connect code. Waits for various prompts (MITO001 etc) and
    writes the bootstrap using a BufferedWriter. On success, switches
    the stream to MitogenProtocol.

  * mitogen.core.Message: move encoding parts of MitogenProtocol out to
    Message (where it belongs) and write a bunch of new tests for
    pickling.

  * The bizarre Stream.construct() is gone now, Option.__init__ is its
    own constructor. Should fix many LGTM errors.

* Update all connection methods:  Every connection method is updated to
  use async logic, defining protocols as required to handle interactive
  prompts like in SSH or su. Add new real integration tests for at least
  doas and su.

* Eliminate manual fd management: File descriptors are trapped in file
  objects at their point of origin, and Side is updated to use file
  objects rather than raw descriptors. This eliminates a whole class of
  bugs where unrelated FDs could be closed by the wrong component. Now
  an FD's open/closed status is fused to it everywhere in the library.

* Halve file descriptor usage: now FD open/close state is tracked by
  its file object, we don't need to duplicate FDs everywhere so that
  receive/transmit side can be closed independently. Instead both sides
  back on to the same file object. Closes #26, Closes #470.

* Remove most uses of dup/dup2: Closes #256. File descriptors are
  trapped in a common file object and shared among classes. The
  remaining few uses for dup/dup2 are as close to minimal as possible.

* Introduce mitogen.parent.Process: uniform interface for subprocesses
  created either via mitogen.fork or the subprocess module. Remove all
  the crap where we steal a pid from subprocess guts. Now we use
  subprocess to manage its processes as it should be. Closes #169 by
  using the new Timers facility to poll for a slow-to-exit subprocess.

* Fix su password race: Closes #363. DelineatedProtocol naturally
  retries partially received lines, preventing the cause of the original
  race.

* Delete old blocking IO utility functions
  iter_read()/write_all()/discard_until().

Closes #26
Closes #147
Closes #169
Closes #256
Closes #363
Closes #419
Closes #470
5 years ago
David Wilson 46ebd56c7a core/master: docstring, repr, and debug log message cleanups
Debug output is vastly more readable now.
5 years ago
David Wilson 3f1ef6e243 master: expect forwarded logs to be in UTF-8.
latin1 was causing corruption of internationalized messages.
5 years ago
David Wilson 2fbc77a155 issue #170: implement timers. 5 years ago
David Wilson ed8acb5153 master: sysconfig did not exist until 2.7. 5 years ago
David Wilson 5eb10aacef master: fix _is_stdlib_path() failure on Ubuntu. 5 years ago
David Wilson 72ab917c89 issue #590: add FinderMethod docstrings. 5 years ago
David Wilson 875ff5c060 issue #590: refactor ModuleFinder and teach it a new special case.
Now it's possible to find both packages and modules when the
sys.modules[...] state for the package/module is junk. Previously only
modules were possible.

This also refactors things to make writing better tests for all these
cases much simpler.
5 years ago
David Wilson 1f77d24bec Update copyright year everywhere. 5 years ago
David Wilson 7ff4e6694c issue #536: rework how 2.3-compatible simplejson is served
Regardless of the version of simplejson loaded in the master, load up
the ModuleResponder cache with our 2.4-compatible version.

To cope with simplejson being loaded due to modules like ec2_group that
try to import it before importing 'json', also update target.py to
remove it from the whitelist if a local 'json' module import succeeds.
5 years ago
David Wilson b263e01867 issue #481: avoid crash if disconnect occurs during forward_modules() 5 years ago
David Wilson 85cfa3b0f5 master: .encode() needed for Py3. 5 years ago
David Wilson 1d509d03ff issue #508: master: minify_safe_re must be bytes for Py3. 5 years ago
David Wilson 0e193c223c issue #508: master: minify all Mitogen/ansible_mitogen sources.
Minify-safe files are marked with a magical "# !mitogen: minify_safe"
comment anywhere in the file, which activates the minifier. The result
is naturally cached by ModuleResponder, therefore lru_cache is gone too.

Given:

    import os, mitogen
    @mitogen.main()
    def main(router):
        c = router.ssh(hostname='k3')
        c.call(os.getpid)
        router.sudo(via=c)

SSH footprint drops from 56.2 KiB to 42.75 KiB (-23.9%)
Ansible "shell: hostname" drops 149.26 KiB to 117.42 KiB (-21.3%)
5 years ago
David Wilson 9adc38d8ec parent: pre-cache bootstrap if possible.
When the interpreter is modern enough, use zlib.compressobj() to
pre-compress the unchanging parts of the bootstrap once, then use
compressobj.copy() to append just the context's config during stream
construction.

Before: 100 loops, best of 3: 5.81 msec per loop
After: 10000 loops, best of 3: 35.9 usec per loop

With 100 targets this is enough to knock 6 seconds off startup, at 500
targets it becomes half a minute.

Test 'program':
        python -m timeit -s '
                import mitogen.parent as p;
                import mitogen.master as m;
                r=m.Router();
                s=p.Stream(r, 0, max_message_size=1);
                r.broker.shutdown()'\
                \
                's.get_preamble()'
5 years ago
David Wilson cafdfdb8e2 master: set Router.profiling if MITOGEN_PROFILING variable present. 5 years ago
David Wilson b8a0e0f929 master: cache sent/forwarded module names
On 32x Docker run of issue_140__thread_pileup.yml

Before:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   384807    3.595    0.000   12.207    0.000 /home/dmw/src/mitogen/mitogen/master.py:896(_forward_one_module)
  1218352    4.867    0.000    7.302    0.000 /home/dmw/src/mitogen/mitogen/master.py:853(_send_module_and_related)

After:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   384807    3.839    0.000    6.543    0.000 /home/dmw/src/mitogen/mitogen/master.py:902(_forward_one_module)
  1218352    0.723    0.000    0.898    0.000 /home/dmw/src/mitogen/mitogen/master.py:856(_send_module_and_related)
5 years ago
David Wilson dc4b27c6bf master: keep is_stdlib_path() result as negative cache entry
On 32x Docker run of issue_140__thread_pileup.yml

Before:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1218500    1.716    0.000    7.325    0.000 /home/dmw/src/mitogen/mitogen/master.py:118(is_stdlib_path)

After:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      166    0.000    0.000    0.001    0.000 /home/dmw/src/mitogen/mitogen/master.py:123(is_stdlib_path)
5 years ago
David Wilson 3435f24e8d issue #479: ModuleFinder special case for __main__ on Py3.x. 5 years ago
David Wilson 4ca3051e39 issue #477: document master.Router.max_message_size. 5 years ago
David Wilson 19eafc5755 issue #477: set().union(a, b, ..) unsupported on Py2.4. 5 years ago
David Wilson e460d648d5 issue #477: Logger.log(extra=) unsupported on Py2.4. 5 years ago
David Wilson 112caa94f9 issue #477: Py2.4 dep scanner bytecode difference 5 years ago
David Wilson 7ecd5d8ba3 issue #477: ModuleFinder test fixes. 5 years ago
David Wilson bc434a4f99 issue #477: backport mitogen.master to Python 2.4. 5 years ago
David Wilson 97a96f5dd8 issue #477: rename and add tests for polyfill functions. 5 years ago
David Wilson 5135ff9068 issue #477: master: ability to override ModuleResponder output.
This is needed to cope Ansible 2.3 doing weird stuff as usual. It serves
up __init__.py for ansible and ansible.module_utils as hard-coded
namespace packages, the real ansible/__init__.py on disk is not 2.4
compatible.
5 years ago
David Wilson 96c35ccab1 issue #61: unused variable (reported by LGTM) 5 years ago
David Wilson 06415bb720 issue #310: fix test failures, teach old import method new tricks
- don't try anything unless something really lives in sys.modules by
  that name
- non-ASCII files are possible
- the unimportable thing might be an extension module, we don't want
  that
5 years ago
David Wilson 6af1a64cce master: handle crazy non-modules in sys.modules again; closes #310. 5 years ago
David Wilson fd90834944 issue #408: fix test fallout. 5 years ago
David Wilson 41626b82dd issue #408: 2.4 compat: remove ternary if use in master.py. 5 years ago
David Wilson cce1dbf3b1 tests: quieten a bunch of spam printed during run 5 years ago
David Wilson b6840aab75 issue #459: one line stats output during shutdown
CI logs are too noisy.
5 years ago
David Wilson f2f41809ae issue #459: initial get_stats() implementation 5 years ago
David Wilson d030decf57 issue #444: master: lower log level for soft import error. 6 years ago
David Wilson 8e4c164d93 issue #388: fix Sphinx markup 6 years ago
David Wilson 804bacdadb docs: move most remaining docstrings back into *.py; closes #388
The remaining ones are decorators which don't seem to have an autodoc
equivlent.
6 years ago
David Wilson 0d04e940b7 master: docstring fixes. 6 years ago
David Wilson 9828588e97 master: group is_stdlib_name() with other module functions. 6 years ago