Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Console issue with Doctrine and custom pdo session handler to store sessions #21775

Closed
Ang3 opened this issue Feb 27, 2017 · 12 comments
Closed

Comments

@Ang3
Copy link

Ang3 commented Feb 27, 2017

Q A
Bug report? yes
Feature request? no
BC Break report? ?
RFC? yes
Symfony version 3.2

Hello,

I had to create a custom PDO session handler so as to share it with another bundle. I configured a PDO Session handler as it explained at http://symfony.com/doc/current/doctrine/pdo_session_storage.html.

I have a SH files to reset my app, drop and create the database, load fixtures, etc. But when the database is dropped, I have an exception : "Database not exists" from Symfony context. I couldn't create it again, and a basic cache clear didn't not work anymore. All commands crashed in fact..

I resolved this problem by adding "lazy: true" to the handler service definition. I post this message because I don't know if it's a normal behaviour. I looked some issues like this one on the web but not related to a PDO session handler to store sessions in database.

@xabbuh
Copy link
Member

xabbuh commented Feb 27, 2017

Does your handler try to connect to the database in its constructor? If so, that is probably the reason for your issue as the service is instantiated by the container and then your connection fails when the database does not exist.

@Ang3
Copy link
Author

Ang3 commented Feb 27, 2017

I just defined the handler like symfony tutorial - I use the default PDO Sessions handler. I had to add the "lazy" option to fix the issue. Maybe it would be useful to add this point on the cookbook ?

@xabbuh
Copy link
Member

xabbuh commented Feb 27, 2017

Can you run the command with -vvv and show the full stack trace that you get for this error?

@Ang3
Copy link
Author

Ang3 commented Feb 27, 2017

Console command : bin/console doctrine:database:create but all commands are affected.

PDO Session handler is shared with Gos/WebSocketBundle but the problem persists even if I break sharing.

Result:

() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:3698 PDO->__construct() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:3698 appDevDebugProjectContainer->getPdoService() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:310 Symfony\Component\DependencyInjection\Container->get() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:4235 appDevDebugProjectContainer->getSession_HandlerService() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:310 Symfony\Component\DependencyInjection\Container->get() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:5718 appDevDebugProjectContainer->getGosWebSocket_Ws_ServerService() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:5707 appDevDebugProjectContainer->{closure}() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:7558 Closure->__invoke() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:7558 GosBundleWebSocketBundleServerTypeWebSocketServer_00000000045d4acb00000000429c767acf7f9e084210842754bc448e7c420554->getName() at /mywebsite/vendor/gos/web-socket-bundle/Server/App/Registry/ServerRegistry.php:27 Gos\Bundle\WebSocketBundle\Server\App\Registry\ServerRegistry->addServer() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:2617 appDevDebugProjectContainer->getGosWebSocket_Server_RegistryService() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:310 Symfony\Component\DependencyInjection\Container->get() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:2356 appDevDebugProjectContainer->getGosWebSocket_EntryPointService() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:310 Symfony\Component\DependencyInjection\Container->get() at /mywebsite/var/cache/dev/appDevDebugProjectContainer.php:2632 appDevDebugProjectContainer->getGosWebSocket_ServerCommandService() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:310 Symfony\Component\DependencyInjection\Container->get() at /mywebsite/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:141 Symfony\Bundle\FrameworkBundle\Console\Application->registerCommands() at /mywebsite/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:108 Symfony\Bundle\FrameworkBundle\Console\Application->all() at /mywebsite/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:72 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /mywebsite/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:120 Symfony\Component\Console\Application->run() at /mywebsite/bin/console:28

@jjsaunier
Copy link

jjsaunier commented Feb 27, 2017

Have you try to add lazy: true on the PDO service ? Tell me if i'm wrong, but CLI is not lazy loaded (as far as I know) , so PDO service might be loaded through gos console command ?

@Ang3
Copy link
Author

Ang3 commented Feb 28, 2017

Indeed, like I said before the only way to solve this issue was to add this "lazy" option. I just wanted to know if that behaviour is normal because the cookbook does not relate to that requirement.

As to me, all external connection interfaces must be set as a "lazy" service sa soon as we want to manage these services internally by running commands like "doctrine:database:create". Also, perhaps the WebSocketBundle is calling directly the PDO constructor without checking its status and in this case my post should not be there.. That's my question in fact :-)

@xabbuh
Copy link
Member

xabbuh commented Feb 28, 2017

Is this websocket service something you wrote yourself? Does it try to access the session in its constructor? Can you share the code?

@Ang3
Copy link
Author

Ang3 commented Feb 28, 2017

No I just installed the bundle Gos/WebSocketBundle and followed the doc. We have to define a PDOSession Handler (not native one) and share it with config.yml. What kind of code could I share ?

@xabbuh
Copy link
Member

xabbuh commented Feb 28, 2017

Would you mind pasting the getGosWebSocket_Ws_ServerService() from your appDevDebugProjectContainer.php file somewhere?

@Ang3
Copy link
Author

Ang3 commented Feb 28, 2017

I filtered by selecting function related on getGosWebSocket_Ws_ServerService().

/**
 * Gets the 'gos_web_socket.client_storage' service.
 *
 * This service is shared.
 * This method always returns the same instance of the service.
 *
 * @return \Gos\Bundle\WebSocketBundle\Client\ClientStorage A Gos\Bundle\WebSocketBundle\Client\ClientStorage instance
 */
protected function getGosWebSocket_ClientStorageService()
{
    $this->services['gos_web_socket.client_storage'] = $instance = new \Gos\Bundle\WebSocketBundle\Client\ClientStorage(900, $this->get('monolog.logger.websocket', ContainerInterface::NULL_ON_INVALID_REFERENCE));

    $instance->setStorageDriver($this->get('gos_web_socket.server.in_memory.client_storage.driver'));

    return $instance;
}

/**
 * Gets the 'gos_web_socket.server.in_memory.client_storage.driver' service.
 *
 * This service is shared.
 * This method always returns the same instance of the service.
 *
 * @return \Gos\Bundle\WebSocketBundle\Client\Driver\InMemoryDriver A Gos\Bundle\WebSocketBundle\Client\Driver\InMemoryDriver instance
 */
protected function getGosWebSocket_Server_InMemory_ClientStorage_DriverService()
{
    return $this->services['gos_web_socket.server.in_memory.client_storage.driver'] = new \Gos\Bundle\WebSocketBundle\Client\Driver\InMemoryDriver();
}

/**
     * Gets the 'gos_web_socket.ws.server' service.
     *
     * This service is shared.
     * This method always returns the same instance of the service.
     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
     *
     * @param bool    $lazyLoad whether to try lazy-loading the service with a proxy
     *
     * @return \Gos\Bundle\WebSocketBundle\Server\Type\WebSocketServer A Gos\Bundle\WebSocketBundle\Server\Type\WebSocketServer instance
     */
    public function getGosWebSocket_Ws_ServerService($lazyLoad = true)
    {
        if ($lazyLoad) {

            return $this->services['gos_web_socket.ws.server'] = GosBundleWebSocketBundleServerTypeWebSocketServer_000000002c3964fa000000007aac0ec9cf7f9e084210842754bc448e7c420554::staticProxyConstructor(
                function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) {
                    $wrappedInstance = $this->getGosWebSocket_Ws_ServerService(false);

                    $proxy->setProxyInitializer(null);

                    return true;
                }
            );
        }

        $instance = new \Gos\Bundle\WebSocketBundle\Server\Type\WebSocketServer($this->get('gos_web_socket.server.event_loop'), $this->get('debug.event_dispatcher'), $this->get('gos_web_socket.periodic.registry'), ${($_ = isset($this->services['gos_web_socket_server.wamp_application']) ? $this->services['gos_web_socket_server.wamp_application'] : $this->getGosWebSocketServer_WampApplicationService()) && false ?: '_'}, $this->get('gos_web_socket.origins.registry'), false, $this->get('gos_web_socket.wamp.topic_manager'), $this->get('gos_web_socket.server_push_handler.registry'), $this->get('monolog.logger.websocket', ContainerInterface::NULL_ON_INVALID_REFERENCE));

        $instance->setSessionHandler($this->get('session.handler'));

        return $instance;
    }

/**
 * Gets the 'gos_web_socket.server.registry' service.
 *
 * This service is shared.
 * This method always returns the same instance of the service.
 *
 * @return \Gos\Bundle\WebSocketBundle\Server\App\Registry\ServerRegistry A Gos\Bundle\WebSocketBundle\Server\App\Registry\ServerRegistry instance
 */
protected function getGosWebSocket_Server_RegistryService()
{
    $this->services['gos_web_socket.server.registry'] = $instance = new \Gos\Bundle\WebSocketBundle\Server\App\Registry\ServerRegistry();

    $instance->addServer(${($_ = isset($this->services['gos_web_socket.ws.server']) ? $this->services['gos_web_socket.ws.server'] : $this->getGosWebSocket_Ws_ServerService()) && false ?: '_'});

    return $instance;
}

@Tobion
Copy link
Contributor

Tobion commented Mar 23, 2017

This looks like the standard doctrine/DoctrineBundle#351 problem and not related the the pdo session thing as you say it happens with any command after the database is deleted.

@xabbuh
Copy link
Member

xabbuh commented Apr 14, 2017

closing for the reasons stated by @Tobion

@xabbuh xabbuh closed this as completed Apr 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants