Opened 18 months ago

Last modified 17 months ago

#3512 new defect

[windows] pid file missing

Reported by: xonqnopp Owned by:
Priority: patches-accepted Milestone: undecided
Version: 0.8.12 Keywords: windows pid
Cc: rutsky

Description

On windows, the PID file twistd.pid is not created upon start. This results in the impossibility to stop buildbot, as the stop command does not see any PID file and says buildbot is not running.

Change History (4)

comment:2 Changed 17 months ago by rutsky

  • Cc rutsky added

comment:3 Changed 17 months ago by rutsky

Related Twisted issues: https://twistedmatrix.com/trac/ticket/2646 https://twistedmatrix.com/trac/ticket/4073

Looks like Twisted on Windows doesn't support daemonization — Windows is not POSIX complaint and requires custom approach for launching processes as daemons.

I don't think it's feasible to wait for daemonization on Windows support in Twisted (just look at how stale are those bugs), so we need to handle this issue at our side.

Currently Buildbot master/worker on Windows just don't daemonize, so we can say that on Windows master and workers are effectively run with --nodaemon and raise error if commands like stop or restart are used (they don't work anyway).

Other option would be to try some cheap solution that will look like daemonization, e.g. spawning twistd script with os.P_DETACH and explicitly writing/reading pid files. This will not be proper daemonization (I believe such "daemons" won't survive user logoff/logon on Windows), but this will good enough for local testing/developing on Windows (and for e2e tests that I'm trying to implement).

@xonqnopp I see in SO question that you added workaround for PID file creation, can you share your code and experience of how good/bad you solution works?

comment:4 Changed 17 months ago by xonqnopp

First here is my code in master.cfg:

## We need to trick twistd as it does not do what it is supposed to:
if not os.path.exists("twistd.pid"):
    with open("twistd.pid", "w") as pidfile:
        pidfile.write("{}".format(os.getpid()))
else:
    realpid = os.getpid()
    filepid = 0
    with open("twistd.pid", "r") as pidfile:
        filepid = int(pidfile.read())
    if filepid == 0 or filepid != realpid:
        with open("twistd.pid", "w") as pidfile:
            pidfile.write("{}".format(realpid))

When running buildbot manually, it works well. The problem is that the PID file is never deleted... The only danger is if you execute:

buildbot start
buildbot stop
buildbot stop

as it would try to kill the process having the PID stored in the file. In the best case, there is no process with this PID and it issues an error. In the worst case, you would kill another random process...

I did not try the workaround with buildbot running as a windows service, since I cannot do this on my computer and the only one we have configured so is not to be broken :-S

It also does not work for the slaves because the workaround is in the master.cfg file...

Note: See TracTickets for help on using tickets.