[Command] Add support for single-process commands #3586

Closed
pkruithof opened this Issue Mar 13, 2012 · 12 comments

Comments

Projects
None yet
9 participants
Contributor

pkruithof commented Mar 13, 2012

I frequently need a command to only run by one process at a time. Most of the time this command would be invoked by a cronjob, but it would not have finished by the time the crontab executes this command again (think long imports and such).

It's fairly easy to fix this by setting a pidfile, and checking for existence (and running process), but it's tedious to do this, and I think it would be a nice feature to implement a "isSingleProcess" method in your command, or something, to accomplish this.

I have implemented this myself, and so if this is a desired feature, I can attach some code to this issue. Also, I'm not really sure what the technical term for this is (it's not a daemon, but I don't know how this is commonly called).

Owner

fabpot commented Mar 13, 2012

It is a not so trivial issue to fix (I mean, if we want to do it right and avoid any race condition -- what if for instance a script writes the pidfile and it then dies without removing the pidfile? You need to check that the process is still running and the way to do this depends on the filesystem).

-1 to add this support to Symfony.

Contributor

pkruithof commented Mar 13, 2012

It's fairly easy to check if a process is still running, or has died, using the posix_kill function, with the 0 (null) signal. I'm sure this can be done without posix as well.

Member

Seldaek commented Mar 13, 2012

I think it's doable in a decent way for unix, but it's probably be hard to make it work on windows. Then again I would still welcome such a feature. It's just hard to make generic enough. Another feature that would be nice is a timeout, so that if a process just hangs for some reason (IO deadlock or whatever) it gets killed anyway after X seconds. Say isSingleProcess(3600) would kill the other processes if they took too long.

Contributor

pkruithof commented Mar 13, 2012

On a side note, maybe it's better to have this in the command definition, rather than implementing a method.

Contributor

xanido commented Mar 14, 2012

@CodeMeme wrote a wrapper for the System_Daemon Pear package which basically does what you want https://github.com/CodeMeme/CodeMemeDaemonBundle

Contributor

dlsniper commented May 26, 2012

If @fabpot doesn't really like this in the core and there's a bundle that can handle the requested feature should this issue be closed or should it be implemented by someone? If it's the later then I could pick it up and start working on something.

Owner

fabpot commented May 27, 2012

If we can implement something that works reliably on both Linux and Windows, I'm +1. But without seeing a working implementation, it's difficult to say if I would accept it in core or not.

Contributor

cordoval commented Dec 4, 2013

if i am not mistaken this can be closed @fabpot as we now hace Process component 👶

Owner

fabpot commented Dec 5, 2013

@cordoval This issue is not related to the Process component.

Sharom commented Dec 29, 2013

@fabpot, I think, that POSIX support is more important. And a think, that we can implement it for POSIX at the first time with abstract interfaces for all components and implement Windows support later. Because Windows Server used rarely than Unix in production and on php-developers' computers.

Member

romainneutron commented Mar 13, 2014

Hey @jakzal, could you label this issue console instead of process ?

@stof stof added Console and removed Process labels Mar 13, 2014

Member

stof commented Mar 13, 2014

@fabpot fabpot closed this Sep 22, 2014

fabpot added a commit that referenced this issue Sep 22, 2014

feature #10475 [Filesystem] Added a LockHandler (lyrixx)
This PR was merged into the 2.6-dev branch.

Discussion
----------

[Filesystem] Added a LockHandler

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #9357 , #3586
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/3956/files

Code sample:

```php
    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $lockHelper = new LockHandler('/tmp/acme/hello.lock');
        if (!$lockHelper->lock()) {
            $output->writeln('The command is already running in another process.');

            return 0;
        }

        $output->writeln(sprintf('Hello <comment>%s</comment>!', $input->getArgument('who')));

        for (;;) {
        }

        $output->writeln(sprintf('bye <comment>%s</comment>!', $input->getArgument('who')));

        $lockHelper->unlock();
    }
```

![process-lock](https://f.cloud.github.com/assets/408368/2443205/4f0bf3e8-ae30-11e3-9bd4-78e09e2973ad.png)

Commits
-------

9ad8957 [Filesystem] Added a lock handler
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment