Commit Graph

402 Commits (49eae23f920be56178a6cedbceb977e0de432f3b)

Author SHA1 Message Date
David Wilson 7698f86a9f Whups, don't always enable profiling in mitogen.main() 7 years ago
David Wilson 52d980ad58 issue #155: fork: nop out get_boot_command, it's become quite expensive
-16% reduction in fork cost.
7 years ago
David Wilson e7c98e3bda Have mitogen.main(profiling=True) effect the master process too 7 years ago
David Wilson a868498469 Replace assertions with fixed checks; closes #157. 7 years ago
David Wilson 4dc001f496 parent: fire disconnect upon receiving DEL_ROUTE for context
This lets context.shutdown(wait=True) succeed in the master or any
parent.
7 years ago
David Wilson 862ec21160 core: allow shutdown triggered by any parent, not just immediate parent 7 years ago
David Wilson 0f08783330 core: fix NameError on disconnect 7 years ago
David Wilson 3e384db7c2 service: add basic security policy types. 7 years ago
David Wilson 2ea65420d0 issue #155: fork.py v2, now with full resource cleanup 7 years ago
David Wilson 872181bebd issue #155: core: implement Side._on_fork()
Central mechanism for deleting all non-Latch file descriptors belonging
to the parent process during fork().
7 years ago
David Wilson 80642ed9ec issue #155: core: remove one duplicate set_cloexec(). 7 years ago
David Wilson cb71ce94c4 issue #155: core: be more careful reconfiguring stdio
Many dragons present!
7 years ago
David Wilson 443c94eb39 issue #155: core: prevent set_cloexec() use on standard handles 7 years ago
David Wilson 41ae6623c6 issue #155: parent: generic name generation
Let us override a class attribute to specify prefix from fork.py, rather
than reimplement the same logic.
7 years ago
David Wilson 22cc1a3689 issue #155: core: refactor Latch to avoid TLS use
TLS destructors are not called after fork, therefore we must explicitly
track a global list of free file descriptors, and arrange for that list
to explicitly be destroyed from fork.py.
7 years ago
David Wilson 2cf9edc895 issue #155: core: ensure reused Importer gets new Context reference.
More hacky layering violations.. force Importer's _context attribute to
our new parent.
7 years ago
David Wilson cd5b37ea5b core: Use Side.read() rather than bare os.read(). 7 years ago
David Wilson 1155de85af issue #155: parent: propagate context name too.
This allows context_by_id() in the master to succeed in returning a
Context with a .name matching the context's name, needed for correct
logging.

Previously this would have logged the empty string, because the master
had no mechanism to know the name of a context created by a child.
7 years ago
David Wilson 19d17982f3 core: Split blocking and non-blocking Latch.get()
Mostly just to avoid embarrassing function size, but it may come in
useful for testing later.
7 years ago
David Wilson cba3347556 issue #155: move connection factories to parent.py. 7 years ago
David Wilson 972f77c6b5 parent: have close_nonstandard_fds() ask OS for FD_MAX 7 years ago
David Wilson 721caafb33 core: Do not decrement Latch._waking if we weren't woken. 7 years ago
David Wilson f6c24ab615 issue #155: don't inherit TLS state in mitogen.fork
This is a partial fix to a general problem: deciding which bits of state
to keep from the parent, and which to clear out. When forking from a
heavily threaded process, there will be 2x$n_threads fds just sitting
around doing nothing, due to Latch use in the parent.

We can't just close all nonstandard fds post-fork, since user code may
be expecting some FDs to be preserved.
7 years ago
David Wilson 67e0a4fe59 issue #155: add mitogen.fork to Importer list 7 years ago
David Wilson 48351a1889 issue #155: parent: support Context.shutdown(), reap children on exit.
This permits graceful shutdown of individual contexts, without tearing
down everything.

Update mitogen.parent.Stream to also wait for the child to exit, to
prevent the buildup of zombie processes. This introduces a blocking wait
for process exit on the Broker thread, let's see if we can get away with
it. Chances are reasonable that it'll cause needless hangs on heavily
loaded machines.
7 years ago
David Wilson 6a74edce6b issue #155: parent: move master.Context into parent.
The Context and Router APIs for constructing children and making
function calls should be available in every parent context, as user code
wants to have access to the same API.
7 years ago
David Wilson f752653e77 core: IoLogger: don't set O_CLOEXEC on standard handles
nested_test was failing due to the recent change to centralize
O_CLOEXEC, since stdout and stderr were being marked as non-inheritable.
That meant child processes would start with no stdout/stderr, triggering
a race between Waker opening its pipes, and IoLogger dup2'ing its pipes
over the stdio handles.

Since the stdio handles were closed, Waker would receive one of them as
one end of its pipe, and consequently have it overwritten by IoLogger.

When IoLogger dups over the top of fd 2, it becomes possible for
Waker.on_read() to be called due to pipe's other end to be closed,
causing an OSError exception with errno EAGAIN to appear.
7 years ago
David Wilson 0eeba2eaa8 core: include fds in Waker repr 7 years ago
David Wilson 7a061fe18b core: merge restart() into io_op()
Any long-running system call may suffer EINTR, so arrange for all IO
calls to be wrapped in the restart loop.
7 years ago
David Wilson 90791768be issue #155: core: slightly rearrange how shutdown works
This eliminates Context.on_disconnect() and instead moves its
functionality to a signal wired up by ExternalContext.main().

It leaves mitogen.master.Context is in a better condition to move into
mitogen.parent where it belongs.
7 years ago
David Wilson 1a8ac9f4d1 issue #155: introduce mitogen.fork / Router.fork() 7 years ago
David Wilson db1b5f7d62 issue #155: core: refactor main() to support forking.
* Split setup_globals() from setup_package() and make package setup
  optional (fork never needs it -- synthetic package already exists in
  children and the real package exists in masters).

* Add main() parameter to allow passing in the existing Importer
  instance. In forks from children, this means we inherit all the cached
  module state along with the __loader__ used to import any existing
  modules.
7 years ago
David Wilson 878e7a0902 issue #155: pass reference to existing Router into Stream constructor
This is a hacky layering violation, but it seems the simplest approach
for now: fork needs access to Router, in order to recover the existing
Importer instance.
7 years ago
David Wilson 21ef540cd8 issue #155: parent: split create_socketpair() from create_child() 7 years ago
David Wilson c31a177ebe issue #155: parent: split get_main_kwargs() from get_preamble() 7 years ago
David Wilson b51365209e parent: needless duplicate ADD_ROUTE message
notice_stream() does that already.
7 years ago
David Wilson a956aa409e Remove duplicate set_cloexec calls everywhere
Now it's handled in Side() constructor, it can disappear elsewhere.
7 years ago
David Wilson f6b5d9f2f6 issue #162: implement mitogen.service.DeduplicatingService
This abstracts the pattern found in parent.ModuleForwarder and to a
lesser degree master.ModuleResponser. We can probably use it in those
contexts later.
7 years ago
David Wilson 65fcef2374 core: mark every side O_CLOEXEC
Not sure why this wasn't done before, seems it should have always been
this way, and can't see any reason it wasn't. Without it, many fds are
leaked into at least .local() children. Closes #163.
7 years ago
David Wilson 08612d4ca2 issue #155: fix call_function_test regression
It's entirely unclear how test_aborted_on_local_context_disconnect ever
passed, but it was broken by the previous commit.
7 years ago
David Wilson 54ff1c90fa issue #155: add DEL_ROUTE, propagate ADD_ROUTE upwards
* IDs are allocated by the parent responsible for contructing a new
  child, using ALLOCATE_ID to the master as necessary to allocate new ID
  ranges.

* ADD_ROUTE is sent up the tree rather than down. This permits
  construction of the new context to complete concurrent to parent
  contexts learning about its existence. Since all streams are strictly
  ordered, it's not possible for any parent to observe messages from the
  new context prior to arrival of an ADD_ROUTE from the parent notifying
  of its existence.

  If the new context, for example, implements an Ansible async task, its
  parent can start executing that without waiting for any synchronous
  confirmation from any parent or the master.

* Since routes propagate up, it's no longer possible for a plain
  non-parent child to ever receive ADD_ROUTE, so that code can be moved
  out of core.py and into parent.py (-0.2kb compressed).

* Add a .routes attribute to parent.Stream, and respond to disconnection
  signal on the stream by propagating DEL_ROUTE for any ADD_ROUTE ever
  received from that stream.

* Centralize route management in a new parent.RouteMonitor class
7 years ago
David Wilson 469279d9ca master: refactor ThreadWatcher
In order to support a .remove() method, to prevent a minor but annoying
(log visible) memory leak while running the tests.
7 years ago
David Wilson e3209d1de0 core: log Broker's id in repr. 7 years ago
David Wilson f4ba66e3ee issue #155: allocate child IDs in batches of 1000.
Avoids a roundtrip for every fork.
7 years ago
David Wilson 7ec02f9bb0 issue #156: ensure Latch state is cleaned up if select throws. 7 years ago
David Wilson 20f5d89dfa issue #156: fix several more races
* Don't need to sleep if queue>sleepers, can just pop the right queue
  element and return it.

* If queue>sleeping and waking==sleeping, no mechanism existed to ensure
  a thread newly added to sleeping would ever be woken. Above change
  fixes that.

* Cannot trust select() return value, scheduler might sleep us
  indefinitely while put() writes a byte.

* Sleeping threads didn't pop FIFO, they popped in whatever order
  scheduler woke them up. Must recover index and use it to pick the pop
  index.
7 years ago
David Wilson 526b0a514b issue #156: prevent Latch.close() triggering spurious wakeups 7 years ago
David Wilson 2c22c41819 issue #156: don't decrement `waking` if we timed out rather than being woken. 7 years ago
David Wilson 07a8994ff5 issue #156: waking thread result dictionary with an integer. 7 years ago
David Wilson 001e0163fe issue #156: handle multiple _put() before wake of first sleeper
- If latch.get() is called and the queue is empty, a thread is put to
  sleep.

- If Latch.put() from another thread then appends an item to the queue and
  wakes the sleeping thread, and

- If a subsequent Latch.put() from the same or another thread manages to
  acquire `lock` before the sleeping thread is scheduled,

- The sleeping thread's wake socket would have multiple bytes written to
  it.

Therefore create a new _pending variable to track the only item assigned
to each thread (keyed by its write socket), and remove the socket from
`sleeping` from within put.
7 years ago
David Wilson 168a954d90 issue #156: prefix Latch private variables 7 years ago
David Wilson 512ff77a46 issue #156: prevent non-sleeping threads from starving sleeping threads.
See new docs
7 years ago
David Wilson c51eee3c7f issue #156: make Pool repr log thread too. 7 years ago
David Wilson c20c2587d9 issue #156: make Latch() repr match Pool() repr. 7 years ago
David Wilson 7f4b89b7bb issue #156: log worker thread crashes in mitogen.pool 7 years ago
David Wilson 6e368d37da issue #156: log queue size too 7 years ago
David Wilson 037b461c39 issue #156: yet more logging :( 7 years ago
David Wilson 653c73c8f0 issue #156: also log target of wakes 7 years ago
David Wilson a5cc7cb43c issue #156: add extra debugging around Latch
Change from writing '\x00' to writing '\x7f', and verify that is the
byte that woke the sleeping thread. Add a bunch more IO logging.
7 years ago
David Wilson ac7a64dfa3 core: assign common expression to a variable. 7 years ago
David Wilson 148ce1d703 issue #155: increase context ID width to 32 bits
Needed to make large range allocations (1000 per ALLOCATE_ID roundtrip)
feasible.
7 years ago
David Wilson f241eac5ce parent: allow Python to determine its install prefix from argv[0]
Fixes support for virtualenv. Closes #152.
7 years ago
David Wilson 9cf889b846 issue #144: master: public/private Pool attributes. 7 years ago
David Wilson fe900087a2 issue #144: service: working service.Pool object.
It knows how to dispatch messages from multiple receivers (associated
with multiple services) to multiple threads, where the service
implementation is invoked on the message.

It wakes a maximum of one thread per received message.

It knows how to shut down gracefully.

Implication: due to the latch use, there are 2 file descriptors burned
for every thread. We don't need interruptibility here, so in future, it
might be nice to allow swapping a diferent queueing primitive into
Select (maybe a subclass?) just for this case.
7 years ago
David Wilson 4f361be7e7 issue #144: teach Select() to close its latch
Causes all threads sleeping on the select to wake.
7 years ago
David Wilson 8aada2646c core: support throwing LatchError in every sleeping thread
This is to allow Select() to be used as a generic queueing primitive
that supports graceful shutdown.
7 years ago
David Wilson ebfe733914 core: tidy up Stream.on_receive() branches. 7 years ago
David Wilson 86ede62241 issue #150: introduce separate connection multiplexer process
This is a work in progress.
7 years ago
David Wilson eee5423dd9 issue #150: tidy up mitogen.debug output for use next time 7 years ago
David Wilson 9adadb5c3a issue #150: import stack.py hack as mitogen.debug
Usage:
  - insert a call to mitogen.debug() in the desired process
  - kill -USR2 that process
  - observe its controlling TTY produces thread stack dumps
7 years ago
David Wilson df488237d4 core: fix race in PidfulStreamHandler
Need to re-test with the lock held, else >1 threads can end up waiting
for lock then reopening the log repeatedly.
7 years ago
David Wilson a06c92d285 core: enable_debug_logging() should reopen file post-fork. 7 years ago
David Wilson 4691ce0b95 issue #150: ansible: add basic Docker support. 7 years ago
David Wilson eba12e2ee2 issue #139: bump kernel socket buffer size to 128kb
This allows us to write 128kb at a time towards SSH, but it doesn't help
with sudo, where the ancient tty layer is always used.
7 years ago
David Wilson 728a0da8a4 issue #139: eliminate quadratic behaviour from transmit path
Implication: the entire message remains buffered until its last byte is
transmitted. Not wasting time on it, as there are pieces of work like
issue #6 that might invalidate these problems on the transmit path
entirely.
7 years ago
David Wilson a3b4b459fa issue #139: eliminate quadratic behaviour on input path
Rather than slowly build up a Python string over time, we just store a
deque of chunks (which, in a later commit, will now be around 128KB
each), and track the total buffer size in a separate integer.

The tricky loop is there to ensure the header does not need to be sliced
off the full message (which may be huge, causing yet another spike and
copy), but rather only off the much smaller first 128kb-sized chunk
received.

There is one more problem with this code: the ''.join() causes RAM usage
to temporarily double, but that was true of the old solution too. Shall
wait for bug reports before fixing this, as it gets very ugly very fast.
7 years ago
David Wilson ba9a06d0f5 issue #139: core: Side.write(): let the OS write as much as possible.
There is no penalty for just passing as much data to the OS as possible,
it is not copied, and for a non-blocking socket, the OS will just keep
buffer as much as it can and tell us how much that was.

Also avoids a rather pointless string slice.
7 years ago
David Wilson 49db4125d0 issue #139: core: bump CHUNK_SIZE from 16kb to 128Kb
Reduces the number of IO loop iterations required to receive large
messages at a small cost to RAM usage.

Note that when calling read() with a large buffer value like this,
Python must zero-allocate that much RAM. In other words, for even a
single byte received, 128kb of RAM might need to be written.
Consequently CHUNK_SIZE is quite a sensitive value and this might need
further tuning.
7 years ago
David Wilson 8e2b07a54e issue #139: add profiling=True option to mitogen.main(). 7 years ago
David Wilson 017e8105cf issue #131: disable non-blocking IO during UNIX accept()
accept() (per interface) returns a non-blocking socket because the
listener socket is in non-blocking mode, therefore it is pure scheduling
luck that a connecting-in child has a chance to write anything for the
top-level processs to read during the subsequent .recv().

A higher forks setting in ansible.cfg was enough to cause our luck to
run out, causing the .recv() to crashi with EGAIN, and the multiplexer
to respond to the handler's crash by calling its disconnect method. This
is why some reports mentioned ECONNREFUSED -- the listener really was
gone, because its Stream class had crashed.

Meanwhile since the window where we're waiting for the remote process to
identify itself is tiny, simply flip off O_NONBLOCK for the duration of
the connection handshake. Stream.accept() (via Side.__init__) will
reenable O_NONBLOCK for the descriptors it duplicates, so we don't even
need to bother turning this back off.

A better solution entails splitting Stream up into a state machine and
doing the handshake with non-blocking IO, but that isn't going to be
available until asynchronous connect is implemented. Meanwhile in
reality this solution is probably 100% fine.
7 years ago
David Wilson 44d36eccba issue #146: don't crash during on_broker_shutdown
There is some insane unidentifiable Mitogen context (the local context?)
that instantly crashes with a higher forks setting. It appears to be
harmless, but meanwhile this naturally shouldn't be happening.
7 years ago
David Wilson cb620500d1 issue #131: log stack and PPID with MITOGEN_ROUTER_DEBUG=1 7 years ago
David Wilson 83c8412474 issue #140: permit mitogen.unix.connect() to accept preconstructed Broker.
Part of an effort to make resource management a little more explicit.
7 years ago
David Wilson 65df36895e issue #140: prevent duplicate watcher thread creation
When a Broker() is running with install_watcher=True, arrange for only
one watcher thread to exist for each target thread, and to reset the
mapping of watchers to targets after process fork.

This is probably the last change I want to make to the watcher feature
before deciding to rip it out, it may be more trouble than it is worth.
7 years ago
David Wilson 1b93a4f51a issue #141: remove reference to incomplete change 7 years ago
David Wilson 587256bbce issue #141: unify connect deadline handling
Now there is a single deadline calculated by the parent.Stream
constructor, and reused for both SSH and sudo.
7 years ago
David Wilson d58b5ad777 core: prevent creation of unicode Message.data
Was triggering a crash indirectly due to Ansible passing us Unicode
strings. Needs a better fix.
7 years ago
David Wilson 31065ffe4a issue #143: avoid long-form options in sudo.py. 7 years ago
Alex Willmer f95b37429f parent: Read preamble in first stage with os.fdopen()
SSH command size: 439 (+4 bytes)
Preamble size: 8941 (no change)

This _increases_ the size of the first stage, but
- Eliminates one of the two remaining uses of `sys`
- Reads the preamble as a byte-string, no call `.encode()`
   is needed on Python 3 before calling `_()`
7 years ago
Alex Willmer a62edd0b7e parent: Use os.execl in first stage
SSH command size: 435 (-4 bytes)
Preamble size: 8962 (no change)

os.execl is the same as os.execv, but it take a variable number of
arguments instead of a single sequence.
7 years ago
Alex Willmer 545652c34f parent: Trim whitespace & e variable in first stage
SSH command size: 439 (-4 bytes)
Preamble size: 8962 (no change)
7 years ago
Alex Willmer 0336de6722 parent: Combine first stage imports
SSH command size: 443 (-5 bytes)
Preamble size: 8962
7 years ago
Alex Willmer 48949cd249 parent: Use 'zip' alias of 'zlib' decoder
SSH command size: 448 (-5 bytes)
Preamble size: 8941 (no change)

NB: The 'zip' alias was absent in Python 3.x, until Python 3.4. This
should change be reverted if Python 3.0, 3.2, or 3.3 support is
required.
7 years ago
Alex Willmer 0f82f68fee parent: Precompute preamble sizes for first stage
SSH command size: 453 (no change)
Preamble size: 8941 (-5 bytes)
7 years ago
Alex Willmer dfd7070ceb parent: reuse _=codecs.decode alias in exec'd first stage
SSH command size: 453 (-8 bytes)
Preamble size: 8946 (no change)
7 years ago
Alex Willmer 53a8c59ae5 parent: Remove redudant os.exit() in first stage
SSH command size: 461 (-8 bytes)
Preamble size: 8946 (no change)

Since python has reached the last statement this should occur anyway.
7 years ago
Alex Willmer e051cf0ea0 parent: Unroll os.close() loop in first stage
SSH command size: 469 (-11 bytes)
Preamble size: 8946 (no change)

Although the source is longer, the _compressed_ length is reduced.
7 years ago
Alex Willmer 85f36f4cb1 parent: Prefer "import foo;x=foo" in first stage
SSH command size: 481 (down 1)
Preamble size: 8946 (no change)
7 years ago
Alex Willmer f999b9adbf Crank zlib.compress() upto 9
SSH command size: 482 bytes (no change)
Preamble size: 8946 bytes (down 33)
7 years ago
David Wilson b243da087c issue #121: fix call_function_test by not raising the dead
A first small mea culpa to all my testing sins of late :)
7 years ago
David Wilson f1009b7502 issue #121: fix breakage caused by a9c6c13
This actually addresses multiple problems:

* Single-file programs were broken, since the fix introduced in
  6931cc10c4 caused builtin_find_module()
  to start indicating __main__ can always be loaded locally. That's
  broken, and there might be more cases where the same problem will crop
  up.

  Since it was indicated __main__ could be loaded locally, the built-in
  import machinery was allowed to attempt that (since we remove __main__
  from sys.modules during bootstrap), which caused a safety check to
  fire in the bowels of Python:

      "Cannot re-init internal module %.200s"

* The check for presence of the whitelist was totally broken, since the
  whitelist is never an empty list. Therefore 'self' was being returned
  for every module, including extension modules like 'termios'.

I have hand-verified this does not break the fix for issue #113. I
looked at writing a test for that, but it requires a Docker container
(or similar) with an ancient version of Ansible installed. Will open a
separate ticket tracking this.
7 years ago
David Wilson 5dddee62ea Revert "issue #121: minimal fix for nested_test."
Mega broken.

This reverts commit a7dbbd96aa.
7 years ago
David Wilson a0c4df72b0 issue #121: minimal fix for nested_test. 7 years ago
David Wilson b2a433dcc4 ssh: CompressionLevel is a v1-only option.
It's ignored by newer SSHes, which only pay attention to Compression.
7 years ago
Alex Willmer 2c05958ecc docs: Replace google.com as target of get_url()
Probably best to avoid angering the 800 lb gorilla with access to killer
robots.

https://example.org works, this is why it exists.
7 years ago
Alex Willmer 1c20c61605 docs: Convert all URLs that support https://
Excluded: graphml XML namespaces, links to e.g. Fabric homepage

Fixes #128
7 years ago
David Wilson 8329bee889 parent: log discard_until() input when IOLOG is enabled
Trying to diagnose a Reddit user's problem.
7 years ago
David Wilson 016d47aa91 Log and track PIDs everywhere for Ansible. 7 years ago
David Wilson 28afa955a3 importer: take priority over system packages when whitelisting is enabled
Might want to de-overload the meaning of whitelist in future, but in
the meantime it works fine for Ansible and I can't think of a
whitelisting use case that would break because of it.

Closes #114.
7 years ago
David Wilson 7aca02c2c7 importer: don't include related modules that are blacklisted
Cuts down on even more spam
7 years ago
David Wilson 37d38f8d9f importer: _is_stdlib_name() needed to handle relative paths
Was causing tons of log spam due to 'skipping absent related name'
7 years ago
David Wilson cf01c6b710 importer: avoid duplicate module load(!); closes #113.
Amazed this one managed to scrape through for so long. Calling
__import__ from within find_module() was causing the target module, in
this case cookielib, to be loaded *then overwritten* by a subsequent
duplicate load higher in the stack.

The result is that cookielib was loaded twice, and, per usual Python
import semantics, a reference to the partially initialized first
cookielib was installed in sys.modules while its code executed.

At the end of cookielib on 2.x, it imports _LWPCookieJar, which in turn
imports the partially built cookielib from sys.modules, then subclasses
the CookieJar from /that/ module.

Everything is wonderful. Then the call returns back up into the import
mechanism which restarts the entire process -- only this time,
_LWPCookieJar is /not/ reinitialized, so the copy in sys.modules is
still left with types pointing at the old module!

So the duplicate import creates a new CookieJar which is not the base
class of LWPCookieJar. Tada! 3 hours debugging.

This is probably a performance fix in disguise, didn't realize things
were so broken. It may also be a regression elsewhere. Urgently need to
finish the tests.
7 years ago
David Wilson 7ab1af043e ansible: redirect logging into display 'framework'. closes #111 7 years ago
David Wilson 5b0b973dba importer: quieten one more warning 7 years ago
David Wilson 6ec349b386 importer: quieten 'cannot find source' warning, closes #110 7 years ago
David Wilson 0ef23d8644 parent: Add hack for OS X /usr/bin/python
It's a magical switcher that needs argv[0], which we don't provide.
7 years ago
David Wilson 88508fcb61 sudo: accept -n too (issue #108) 7 years ago
David Wilson 9cfcf79f43 sudo: accept but discard -S option. fixes #108 7 years ago
David Wilson 95ea75907d ssh: Fix AttributeError. 7 years ago
David Wilson 3ddbf1a503 ansible: basic support for ssh_args 7 years ago
David Wilson 235e1df987 sudo: support parsing sudo flags back out into parameters 7 years ago
David Wilson d348a826ff master: tidy up trixxy importer syntax slightly 7 years ago
David Wilson 7cf2edc3a8 ansible: Support many more common playbook variables. 7 years ago
David Wilson ff617824a1 ansible: fix some flake8 errors
* Unused imports
* Undefined names in helpers.py
* Copyright header wrapping
7 years ago
Alex Willmer 33781aba2c core: Correct naming of Stream.sent_modules
Fixes #90
7 years ago
Alex Willmer d4a546dcbc parent: Fix ModuleForwarder not sending related packages
Found due to a LGTM warning about unused loop variable (related). As far
as I can tell the callback was sending fullname multiple times. KeyError
check added because I found NestedTest failed - mitogen.parent had
mitogen as one of it's related, and mitogen was not in the cache.

Refs #61
7 years ago
Alex Willmer 227cd3aa60 ssh, sudo: Remove redundant else clause on bootstrap loop
Since the for loops don't contain any break statements the StreamErrors
will always be raised when the loop completes without the method
resturning.

See https://lgtm.com/rules/5980098/

Refs #61
7 years ago
Alex Willmer a1aab30e63 core: Implement Dead.__ne__ & Dead.__hash__
Both these addtions are to address warnings in
https://lgtm.com/projects/g/dw/mitogen/alerts/?mode=list. Namely that if
a class defines an equality method then it should also define an
inequality and a hash method.

Refs #61
7 years ago
Alex Willmer 4b373c421b core: Standardise type of Importer.whitelist
This seemed a reasonable streamlining, but I'm happy to be overruled.
7 years ago
Alex Willmer ecaa8609f3 core: Add docstring to is_blacklisted_import()
This documents the existing behaviour, which may not be the intended.
7 years ago
David Wilson 5855f1739f core: Handle unpicklable data in dispatch_calls()
Sending just via .call_async() would previously crash the child, now it
generates CallError like intended.
7 years ago
Alex Willmer 8513b331b7 Use Pythabsoluteon 2.4 compatible module import
Python 2.4 does not support explicit relative imports. They were added
at Python 2.5, along with `from __future__ import absolute_import`.

On 2.x this will mean the import is first (implicitly) tried relative,
but on 3.x it will always be tried absolute.

Fixes #92
7 years ago
David Wilson 5036a9448f Add Docker method. 7 years ago
David Wilson d4169557f1 Fix some more Python 2.4 syntax 7 years ago
Alex Willmer 2dcab3fe06 master: Reword ModuleFinder.find_realted*() docstrings
Hopefully these are correct, and clearerabout the
behaviour/pre-conditions of these methods.
7 years ago
Alex Willmer c2405369d2 ModuleFinder: Get stdlib paths by sys.prefix, sys.real_prefix etc.
I took the liberty of renaming ModuleFinder.STDLIB_DIRS to
_STDLIB_PATHS, since it felt like an implementation detail that
shouldn't be baked into a public API and stdlib can also be imported
from e.g. a zip file.

I also changed it to a set to handle any duplicates.

Fixes #86
7 years ago
David Wilson b221eaaa10 ansible: log call timings 7 years ago
David Wilson afc8697288 core: Ensure add_handler() callbacks really receive _DEAD on shutdown 7 years ago
David Wilson 91116810a1 ansible: delete utils.py and promote cast() to mitogen.utils 7 years ago
David Wilson 18eaf14dca ansible: migrate logging variables into utils. 7 years ago
David Wilson 5d8cb0f5fb ansible: document the connection class. 7 years ago
David Wilson 020036f807 core: add a nasty hack for Ansible modules. 7 years ago
David Wilson fa804c7c80 parent: simplify route() call
Doesn't need to go via defer() since it's always running on the broker
thread.
7 years ago
David Wilson bdd8648bae ssh: enable compression by default
Using the same test as in 7af97c0365,
transmitted wire bytes drops from 135,531 to 133,071 (-1.81%), while
received drops from 21,073 to 14,775 (-30%).

Combined, both changes shave 13,914 bytes (-8.6%) off aggregate
bandwidth usage.

Make it configurable as compression hurts in some scenarios.
7 years ago
David Wilson 4d940f08ae importer: drop redundant prefix from pkg_present
For the 52 submodules of ansible.modules.system, this produced a 1602
byte pkg_present list. After stripping it becomes 406 bytes, and the
entire LOAD_MODULE size drops from 1988 bytes to 792 bytes (-60%).

For the 68 submodules of ansible.module_utils, 1902 bytes pkg_present
becomes 474 bytes (-75%), and LOAD_MODULE size drops from 2867 bytes to
1439 bytes (-49%).

In a simple test running Ansible's "setup" module followed by its "apt"
module, wire bytes sent drops from 140,357 to 135,531 (-3.4%).
7 years ago
David Wilson 71a6b9e32a master: Select.all() sugar 7 years ago
David Wilson b543b84e80 importer: share blacklist logic between master/parent 7 years ago
David Wilson 8ec6ae1da0 importer: module whitelist/blacklist support
Hoped to avoid it, but it's the obvious solution for Ansible.
7 years ago
David Wilson 43ba1c76dc core: wrap selects in EINTR handlers
This isn't nearly enough, but it catches the most common victim of
EINTR.
7 years ago
David Wilson aafe458a13 core: #39: don't call logging framework when logging is disabled
It looks ugly as sin, but this nets about a 20% drop in user CPU time,
and close to 15% increase in throughput.

The average log call is around 10 opcodes, prefixing with '_v and' costs
an extra 2, but both are simple operations, and the remaining 10 are
skipped entirely when _v or _vv are False.
7 years ago