Commit Graph

618 Commits

Author SHA1 Message Date
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.
2018-03-25 10:51:44 +05:45
David Wilson 5579ac936b issue #155: docs: more fork() liability warnings 2018-03-25 10:08:46 +05:45
David Wilson f457f54758 docs: fix formatting 2018-03-24 22:16:06 +05:45
David Wilson d370290687 docs: one more warning 2018-03-24 22:15:24 +05:45
David Wilson 03e08e25fd docs: put huge liability notice in fork() docs. 2018-03-24 22:13:36 +05:45
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.
2018-03-24 21:40:44 +05:45
David Wilson cba3347556 issue #155: move connection factories to parent.py. 2018-03-24 20:23:19 +05:45
David Wilson 972f77c6b5 parent: have close_nonstandard_fds() ask OS for FD_MAX 2018-03-24 20:22:45 +05:45
David Wilson 721caafb33 core: Do not decrement Latch._waking if we weren't woken. 2018-03-24 20:19:48 +05:45
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.
2018-03-24 20:16:25 +05:45
David Wilson 67e0a4fe59 issue #155: add mitogen.fork to Importer list 2018-03-24 19:51:00 +05:45
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.
2018-03-24 19:19:51 +05:45
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.
2018-03-24 19:19:45 +05:45
David Wilson 447353ecb8 docs: ansible.rst: note multi-host perf isn't great right now 2018-03-24 18:54:02 +05:45
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.
2018-03-24 18:47:13 +05:45
David Wilson 0eeba2eaa8 core: include fds in Waker repr 2018-03-24 18:35:07 +05:45
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.
2018-03-24 17:18:11 +05:45
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.
2018-03-24 16:51:31 +05:45
David Wilson 4f93c6823a issue #155: skeletal fork_test. 2018-03-24 16:28:13 +05:45
David Wilson 20780820a6 docs: typo 2018-03-24 15:58:42 +05:45
David Wilson 75b9e1d71e issue #155: docs: document behaviour of forked children 2018-03-24 15:57:03 +05:45
David Wilson 110fdf24cd docs: add mitogen.fork.Stream to internals.rst 2018-03-24 15:53:06 +05:45
David Wilson 1a8ac9f4d1 issue #155: introduce mitogen.fork / Router.fork() 2018-03-24 15:50:28 +05:45
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.
2018-03-24 15:47:21 +05:45
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.
2018-03-24 15:45:51 +05:45
David Wilson 21ef540cd8 issue #155: parent: split create_socketpair() from create_child() 2018-03-24 15:44:59 +05:45
David Wilson c31a177ebe issue #155: parent: split get_main_kwargs() from get_preamble() 2018-03-24 15:43:57 +05:45
David Wilson b51365209e parent: needless duplicate ADD_ROUTE message
notice_stream() does that already.
2018-03-24 15:43:13 +05:45
David Wilson 27175e3126 docs: tidy up signals.rst a little. 2018-03-23 16:52:54 +05:45
David Wilson a956aa409e Remove duplicate set_cloexec calls everywhere
Now it's handled in Side() constructor, it can disappear elsewhere.
2018-03-23 12:41:31 +05:45
David Wilson 732a610246 docs: add beginnings of section on func decorators 2018-03-23 09:31:29 +05:45
David Wilson 2abe87472c issue #162: docs: begin documenting mitogen.service 2018-03-23 09:31:11 +05:45
David Wilson 1777b8f42e ansible: use DeduplicatingService for ContextService; closes #162. 2018-03-23 09:30:41 +05:45
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.
2018-03-23 09:29:39 +05:45
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.
2018-03-23 06:58:59 +05:45
David Wilson 2d7821b824 tests: test_stream_name: fix non-localhost Docker 2018-03-22 13:25:56 +05:45
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.
2018-03-22 12:57:05 +05:45
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
2018-03-22 11:56:24 +05:45
David Wilson aeeeb45ccb docs: farewell, glorious iframe! 2018-03-22 07:13:42 +05:45
David Wilson adfd827531 test.sh: enhancements
* Explicitly name every test to run, I have lots of unchecked in stuff
* Allow SIGINT to stop the process
2018-03-22 05:21:42 +05:45
David Wilson 23e279b617 tests: get import_test limping back to health. 2018-03-22 05:07:31 +05:45
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.
2018-03-22 05:04:59 +05:45
David Wilson e3209d1de0 core: log Broker's id in repr. 2018-03-22 05:04:35 +05:45
David Wilson f4ba66e3ee issue #155: allocate child IDs in batches of 1000.
Avoids a roundtrip for every fork.
2018-03-22 03:41:04 +05:45
David Wilson 0c77107041 issue #96: fail test.sh if any test fails 2018-03-21 11:09:14 +05:45
David Wilson 1ed86774b5 issue #156: document select exception 2018-03-21 09:23:54 +05:45
David Wilson 7ec02f9bb0 issue #156: ensure Latch state is cleaned up if select throws. 2018-03-21 09:22:29 +05:45
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.
2018-03-20 14:53:19 +05:45
David Wilson 526b0a514b issue #156: prevent Latch.close() triggering spurious wakeups 2018-03-20 13:14:51 +05:45
David Wilson 18e2977baf docs: annoying phrasing 2018-03-20 13:05:41 +05:45