Closed bturner closed 2 months ago
@wkritzinger-atlassian, if you have a moment, could you test this with Bitbucket?
I've verified it locally on Linux (x64 only) and macOS (x64 and aarch64, both on native hardware) and Windows (x64 only, not that there should be any risk of a regression on Windows here), so I know all the basics work, but I'd value the more thorough check.
@bturner Apologies for the delay in my response. I ran all of our internal tests against the version that is in this change and it is all green.
I also had a look at this change and it seems good as well. I'll attempt to reproduce our zombie process problem that we're still having and keep you updated when I find something.
No worries, @wkritzinger-atlassian. I appreciate you taking the time to run through it. I'm going to look at a couple other pull requests and then see if I can work through a 2.1 release. Even if it doesn't fix your zombie process issue (and if I'm honest I suspect it won't), at least it will clean up the NullPointerException
s on racy starts for some of the faster git
processes.
Hello, Do you know when a release with that correction will be cut ? We believe we saw it two times IRL now, but it is extremely hard to test/reproduce. Having a version with the patch would help decide if it's the same problem.
Immediately after a
LinuxProcess
is registered withProcessEpoll
, it's possible for soft exit detection to detect process termination. If a process exits quickly, this means it's possible forNuProcessHandler.onExit
to be called beforeonStart
. When that happens,BasePosixProcess.callStart
throws aNullPointerException
because exit cleanup clears the process handler.The top of such a call stack looks something like this:
This change splits the existing
IEventProcessor.registerProcess
method into two:registerProcess
, andqueueRead
(a parallel toqueueWrite
).registerProcess
sets up mappings (pidToProcessMap
,fildesToProcessMap
), and thenqueueRead
does theepoll
(orkevent
, on macOS) operations.This split ensures the process is registered before
onStart
is called, which is necessary to allow process handlers to callwantWrite
duringonStart
, while also ensuringstdout
/stderr
aren't consumed until afteronStart
is called (which, in turn, prevents early soft-exit detection).IEventProcessor.queueRead(T)
registerProcess
(as appropriate for the host OS), and then set upepoll
/kevent
state inqueueRead
NuProcess.run
),queueRead
is called by theProcessEpoll
/ProcessKqueue
constructors. There is no risk of a race because the process classes don't callIEventProcessor.run
(which actually consumes events) until afteronStart
has been called2.1.0-SNAPSHOT
because a new interface method has been addedmvnvm
)