Commit Graph

257 Commits (e6bc53ca3a070e1c2b6c70eb0cc2e2fae7a6b4fa)

Author SHA1 Message Date
David Wilson 87c8ab4323 issue #550: fix up TTY ioctls on WSL 2016 Anniversary Update 5 years ago
David Wilson c1d73e1f4f issue #535: parent: add create_socketpair(size=..) parameter. 5 years ago
David Wilson 9bcd2ec56c issue #542: return of select poller, new selection logic 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 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 cfb94e463f parent: PartialZlib docstrings. 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 7ca927608c parent: synchronize get_core_source()
Single task 100 SSH target run, before:

        3533181 function calls (3533083 primitive calls) in 616.688 seconds
        User time (seconds): 32.52
        System time (seconds): 2.71
        Percent of CPU this job got: 64%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:54.88

After:

        451602 function calls (451504 primitive calls) in 570.746 seconds
        User time (seconds): 29.48
        System time (seconds): 2.81
        Percent of CPU this job got: 67%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:48.20
5 years ago
David Wilson e77048ec2d utils: pad out reset_affinity() and integrate with detach_popen() 5 years ago
David Wilson 568044438d parent: don't kill children when profiling is active. 5 years ago
David Wilson 407294cd79 issue #498: prevent crash on double 'disconnect' signal.
Fixes:

ERROR! [pid 1096] 23:31:48.363215 E mitogen: _broker_main() crashed
Traceback (most recent call last):
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2917, in _broker_main
    self._loop_once()
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2875, in _loop_once
    self._call(side.stream, func)
  File "/home/dmw/src/mitogen/mitogen/core.py", line 2860, in _call
    stream.on_disconnect(self)
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1161, in on_disconnect
    super(Stream, self).on_disconnect(broker)
  File "/home/dmw/src/mitogen/mitogen/core.py", line 1534, in on_disconnect
    fire(self, 'disconnect')
  File "/home/dmw/src/mitogen/mitogen/core.py", line 390, in fire
    func(*args, **kwargs)
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1794, in <lambda>
    func=lambda: self._on_stream_disconnect(stream),
  File "/home/dmw/src/mitogen/mitogen/parent.py", line 1810, in _on_stream_disconnect
    routes = self._routes_by_stream.pop(stream)
KeyError: mitogen.ssh.Stream('ssh.localhost:2236')
5 years ago
David Wilson 9aa845669c issue #413: don't double-propagate DEL_ROUTE to parent.
propagate_up() sends ADD_ROUTE and DEL_ROUTE

propagate_down() sends only DEL_ROUTE, but didn't bother checking if
up() had sent it already.

Fixes:

     ERROR! [pid 41060] 17:55:30.739159 E mitogen.ctx.ssh.localhost:
     mitogen: RouteMonitor(): received DEL_ROUTE for 6081 from
     mitogen.fork.Stream(u'fork.41142'), expected
     mitogen.core.Stream('parent')
5 years ago
David Wilson e2478dcb9f issue #498: wrap Router dict mutations in a lock 5 years ago
David Wilson ec789513dc ssh: tidy up logs and stream names. 5 years ago
David Wilson 4095358ea4 Merge commit '5bd6bd0' into envtest
* commit '5bd6bd0':
  parent: don't send messages on streams that no longer exist; closes #480
5 years ago
David Wilson d0075e7e50 parent: --with-pydebug bootstrap could fail due to corrupted stream
Due to first stage writin 'XXX refs' on exit. So close stderr as last
step of first stage.
5 years ago
David Wilson 2e4d7b15d7 parent: don't kill child when profiling=True 5 years ago
David Wilson 61297c24e5 issue #477: call_function_test fixes for 2.4. 5 years ago
David Wilson f1a712fad3 issue #477: Python<2.5 ioctl() request parameter was signed. 5 years ago
David Wilson 5bd6bd06d1 parent: don't send messages on streams that no longer exist; closes #480 5 years ago
David Wilson ffd46e9f1c issue #477: parent: make iter_read() log disconnect reason. 5 years ago
David Wilson 87d2af4c6e issue #477: polyfill partition() use in mitogen.parent. 5 years ago
David Wilson 07f1b9bdd0 issue #477: Python 2.5 needs next() polyfill too. 5 years ago
David Wilson 0ee8ee78b8 issue #477: Py2.4 cannot tolerate unicode kwargs. 5 years ago
David Wilson f3dae10fe1 issue #477: 2.4/2.5 had no better poller than poll(). 5 years ago
David Wilson 881dc7d5ca issue #477: more 2.4-compatible thread.get_ident() use. 5 years ago
David Wilson fb750edfa7 issue #61: fix bare except (reported by LGTM) 5 years ago
David Wilson 767737265a issue #61: add inverse comparison (reported by LGTM) 5 years ago
David Wilson 51bd35280a issue #61: remove duplicated method (reported by LGTM) 5 years ago
David Wilson ea9ef50b3c issue #415: replace default Poller with select.poll()
30% latency reduction for IPC.
5 years ago
David Wilson fd90834944 issue #408: fix test fallout. 5 years ago
David Wilson 51ac309647 issue #408: 2.4 compat: replace iter_read with explicit generator
Can't use yield inside try/finally on 2.4.
5 years ago
David Wilson 57b652eddc parent: remove unused imports
The stray functools import must have been there forever! Instant 4kb
knocked off wire footprint.
5 years ago
David Wilson de719fa249 core: throw error on duplicate add_handler(); closes #447. 5 years ago
David Wilson 85e965118d Merge remote-tracking branch 'origin/issue462'
* origin/issue462:
  issue #462: docs: update Changelog.
  parent: cope with broken /dev/pts on Linux; closes #462.
5 years ago
David Wilson 8fa3c74de4 issue #426: RouterMonitor format incorrect for 3->2 forward.
Each hop would cause "b''" to be wrapped around the context name.
5 years ago
David Wilson a4c7a98dd9 parent: cope with broken /dev/pts on Linux; closes #462. 5 years ago
David Wilson 2f3a8f2a32 parent: proxy_connect docstring. 6 years ago
David Wilson 3f5774cfd5 core: document/tidy up poller.
Remove duplicate attribute creates in subclasses too.
6 years ago
David Wilson 3876590aa1 parent: add descriptive errors for unsupported call() types.
Closes #439.
6 years ago
David Wilson 045db6f689 Fix iter_read() FD leaks on 3.x; closes #418. 6 years ago
David Wilson 76ec4f201c issue #413: paper over harmless duplicate del_route()
Ideally it would only be called once, and in future maybe it can, but
right now we need to cope with these cases:

* Downstream parent notifies us of disconnection (DEL_ROUTE)
* We notify ourself of disconnection
* We notify ourself and so does downstream parent

It's case 3 that causes the error.
6 years ago
David Wilson 802de6a8d5 issue #406: clean up DiagLogStream handling and connect() failure.
When Stream.connect() fails, have it just use on_disconnect(). Now there
is a single disconnect cleanup path.

Remove cutpasted DiagLogStream setup/destruction, and move it into the
base class (temporarily), and only manage the lifetime of its underlying
FD via Side.close().  This cures another EBADF failure.
6 years ago
David Wilson dc3db49c5a issue #406: more leaked FDs when create_child() fails. 6 years ago
David Wilson 17631b0573 issue #406: parent: close extra_fd on failure too. 6 years ago
David Wilson b3841317dd issue #406: clean up FDs on failure explicitly
The previous approach was crap since it left e.g. socketpair instances
lying around for GC with their underlying FD already closed, coupled
with FD number reuse, led to random madness when GC finally runs.
6 years ago
David Wilson 375182b71b issue #406: don't leak side FDs on bootstrap failure. 6 years ago
David Wilson 14b389cb46 issue #406: don't leak FDs on failed child start. 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 1d32ed3b5a core: avoid shutdown() in IoLogger on WSL; closes #333. 6 years ago
David Wilson f2d288bb1e tests: ensure minify() result can be compiled for all of core. 6 years ago
David Wilson a7ee23719a issue #388: move a ton of documentation back into the source 6 years ago
David Wilson 0394dac2c7 docs: document RouteMonitor class. 6 years ago
David Wilson 71f9e84ab3 Add EOF error hints for LXC/LXD; closes #373. 6 years ago
David Wilson 22b4b186d7 issue #333: add versioning to EpollPoller too. 6 years ago
David Wilson 73cda2994f issue #333: add versioning, initial batch of poller tests
Now poller is start enough to know a start_receive() during an iteration
does not cause events yielded by that iteration to associate with the
wrong descriptor.

These changes are tangentially related to the associated ticket, but
event versioning is still the underlying issue.
6 years ago
David Wilson 58d0a45738 issue #76: quieten routing errors.
Receiving DEL_ROUTE without a corresponding ADD_ROUTE is now legit
behaviour, so don't print an error in this case.

Don't print an error for dropped messages if the reply_to indicates the
sender doesn't care about a response (dead and no_reply)
6 years ago
David Wilson fba52a0edf issue #76: add API for ansible_mitogen to get route list
Earlier commit moved Stream.routes attribute into a private map
belonging to RouteMonitor, to make upgrades smoother. This adds a new
accessor method to RouteMonitor.
6 years ago
David Wilson 431051f69b issue #76: parent: broadcast DEL_ROUTE to interested parties
Now rather than simply propagate DEL_ROUTE upwards towards the parent,
we broadcast it downward to any stream that ever sent a message toward
any of the routes that have just become disconnected.
6 years ago
David Wilson d7d40f1123 issue #76: reduce Context duplication during unpickling
When unpickling a context, arrange for there to be a single instance
representing that context, managed by the corresponding router. This
context_by_id() was already in use by parent.py, it just needs to move
down.

This to eventually reach the point where a single Context exists that
needs 'disconnect' fired on it, so all sleeping receivers are definitely
woken.
6 years ago
David Wilson 3aa5c4c53d issue #373: parse the child process wait status
Don't log the raw waitpid() result, convert it to a useful string first.
6 years ago
dw ad44ad16f1
Merge pull request #385 from moreati/python-3.x-cleanups
Test with Tox on Python 3.x
6 years ago
Alex Willmer 6da31c9dee docs: Remove unneeded backslash escapes
Python 3.x was emitting a DeprecationWarning. AFAICT there has been no
impact on the HTML rendering.
6 years ago
David Wilson 0fa5fe5559 parent: handle masters with blank sys.executable; closes #356. 6 years ago
Yannig Perré 6828926a36 Kubernetes connection support for mitogen. 6 years ago
David Wilson dfc67b89fd docs: some more cleanups
- add faulthandler/thread stacks to changelog.
- various api.rst cleanups.
- docs: explain chain_id in howitworks.
6 years ago
David Wilson 863c1b7597 parent: correct CallSpec name formatting for class methods. 6 years ago
David Wilson e241081cae ansible: stop sharing target temp_dir in runner.
This cannot work with delegate_to, since delegate_to permits multiple
concurrent tasks to be executing on the same target.
6 years ago
David Wilson 42d3f96d14 parent: do updates 6 years ago
David Wilson 43d9815f6d ansible: use CallChain everywhere.
This replaces the 'dump to logger' behaviour of pipelined calls from
before with a call chain that returns any exception on next synchronized
call.
6 years ago
David Wilson 4d3873c784 core: call chains v3: abstract it into a new CallChain class. 6 years ago
David Wilson a52f66328b parent: test fixes. 6 years ago
David Wilson a3957d6aaf parent: add Context.forget_chain(). 6 years ago
David Wilson 7d62a53264 issue #337: ssh: disabling PTYs round 2: make it automatic. 6 years ago
David Wilson c4c6ae88a4 parent: raise a descriptive error when openpty fails. 6 years ago
Jesse London 3453d4d7d0 Python 3 support for classmethod call targets
There were two problems with detection and handling of class methods as call targets in Python 3:

* Methods no longer define `im_self` -- this is now only `__self__`
* The `types` module no longer defines a `ClassType`

The universally-compatible (v2.6+) solution was to switch to using the `inspect` module -- whose interface has been stable -- and to checking the method attribute `__self__`.

(It doesn't hurt that `inspect` checks are more brief and we now no longer need the `types` module here.)
6 years ago
David Wilson 49f3a61164 parent: prevent subprocess.Popen.__del__ from calling waitpid().
Closes #253.
6 years ago
David Wilson ec8d759d46 docs: document one more. 6 years ago
David Wilson 442d88e3d7 docs: many more fixes/merges. 6 years ago
David Wilson 06e2e846c5 parent: don't generate illegal default remote names.
getpass.getuser() output may contain slashes, which must be avoided as
they break virtualenv when present in argv[0].

Closes #344.
6 years ago
David Wilson 81c8156965 Support LXD; closes #339. 6 years ago
David Wilson 22bab87821 issue #319: avoid TCSAFLUSH flag on WSL.
Closes #319.
6 years ago
David Wilson 56943d3141 issue #319: have cfsetraw() generate sensible flags.
Attempting to fix issue on WSL.

Closes #71
6 years ago
David Wilson 50a1bf6f22 issue #300: temporary workaround for shutdown issue.
Closes #300.
6 years ago
David Wilson 1171b06eb5 Merge remote-tracking branch 'origin/issue320' into dmw 6 years ago
David Wilson 76caf7d41d issue #320: ignore kqueue events marked KQ_EV_ERROR.
Since BasicStream.close() invokes _stop_transmit() followed by
os.close(), and KqueuePoller._stop_transmit() defers the unsubscription
until the IO loop resumes, kqueue generates an error event for the
associated FD, even though the changelist includes an unsubscription
command for the FD.

We could fix this by deferring close() until after the IO loop has run
once (simply by calling .defer()), but that generates extra wakeups for
no real reason.

Instead simply notice the error event and log it, rather than treating
it as a legitimate event.

Another approach to fixing this would be to process
_stop_receive()/_stop_transmit() eagerly, however that entails making
more syscalls.

Closes #320.
6 years ago
David Wilson f977be2868 issue #291: permit supplying a full Python argv. 6 years ago
David Wilson 336e90c5e3 parent: avoid needless quoting in Argv.
This just makes debug output a little more readable.
6 years ago
napkindrawing 745d72bb1d core: support for "doas" become_method 6 years ago
David Wilson 692275064b parent: fix TtyLogger str/unicode crash on 3.x. 6 years ago
David Wilson 29f15c236c core: remove needless size prefix from core_src_fd.
I think this is brainwrong held over from an early attempt to write the
duplicate copy of core_src on stdin.
6 years ago
David Wilson 8791d40081 parent: tidy up call_async() logging. 6 years ago
David Wilson 4ff47d6a93 parent: more 2/3x format fixes 6 years ago
David Wilson 6b4e047017 tests: 3.x parent_test fixes. 6 years ago
David Wilson 0422a8c263 parent: python_path setting depends on local or remote
For local, we want to default to the same Python version as the current
process. For remote, we want whatever is on offer.
6 years ago
David Wilson 410016ff47 Initial Python 3.x port work.
* ansible: use unicode_literals everywhere since it only needs to be
  compatible back to 2.6.
* compat/collections.py: delete this entirely and rip out the parts of
  functools that require it.
* Introduce serializable Kwargs dict subclass that translates keys to
  Unicode on instantiation.
* enable_debug_logging() must set _v/_vv globals.
* cStringIO does not exist in 3.x.
* Treat IOLogger and LogForwarder input as latin-1.
* Avoid ResourceWarnings in first stage by explicitly closing fps.
* Fix preamble_size.py syntax errors.
6 years ago
David Wilson d6126a9516 issue #275: parent/ssh: centralize EC0_MARKER and change it for ssh.py.
Must maintain a minimum buffer length prior to deciding whether we have
an interesting token, and 'EC0' is too short for that.
6 years ago
David Wilson fbd5837cf2 issue #275: parent: use TIOCSCTTY on Linux too.
This appears to be harmless, except for Python 2.6 on Linux/Travis,
where for some reason (some stdlib change?) simply opening the TTY is
insufficient.
6 years ago
David Wilson cfd2887292 issue #275: default to 'python' for default remote interpreter.
So we get 2.4/2.5/2.6/2.7/3.x.
6 years ago