Open Leont opened 10 years ago
I guess I should explain what I meant with push-based architecture: right now it's parser->next calling grammar->next calling iterator->next. For this to work sanely it needs to be iterator->on_read calls grammar->push_data calls parser->push_result, or some such. In other words, we need a built-in event-loop.
Not sure if this would help with prove or not, but just gonna state how yath implements things, feel free to ignore:
Yath has each test run with its output redirected to temp files (one for stderr, one for stdout, It also has a hook that make sure anytime Test2/Test-Builder produce an event inside the tests (ok, diag, etc) a timestamp is written to the stderr/stdout files, this gives synchronization points so that stderr and stdout can be lined up (mostly) so that errors do not show up hundreds of lines from the failed assertion, etc.
Yath has a multi-process pipeline to then handle this. The collector process iterates each running jobs temp files collecting events (lines of output). It has a limit of how many events to gather before jumping to the next file, and will never sit and wait for events, this prevents any one job from monopolizing the collector. The collectors output is tied to the next process, the aggregator, the auditor. The Auditor actually processes the collected events and makes sure things are sane, tests pass/fail, etc. It then forwards the processed events, including additional info such as final state, etc to the final process which renders everything and sets the final exit code.
This is of course over-simplified. In all there are 4 yath processes in a typical test run, the runner which spawns each tests, the collector, the auditor and the renderer, the renderer is the original (parent) process and spawns the others with their outputs tied together correctly. (The runner process also redirects to temp files which the collector monitors in case the runner itself has an exception).
for reference, a semi cross post from https://github.com/Perl-Toolchain-Gang/Test-Harness/pull/52
There are some paragraphs of API design concepts and opinions that are more related to this ticket vs that ticket. If someone has ideas on refactoring I/O stuff in T::H in the future.
It hangs and hangs and hangs.
Despite using select the whole architecture of TAP::Harness is based on blocking IO, which is a really poor combination with multiprocessing in particular. I'm not sure how to solve this. TAP::Parser is fundamentally a pull-architecture, while it should have been a push-based architecture. I'm not sure this can be fixed without rewriting TAP::Parser, TAP::Parser::Iterator*, TAP::Parser::Grammar and TAP::Parser::Multiplexer. The entire flow of control/data needs to be reversed :-(.