octane: octane:reload on symlink strategy, doesn't reflect changes

  • Octane Version: 1.0
  • Laravel Version: 8.12
  • PHP Version: 8.0.6
  • Server & Version: Swoole
  • Database Driver & Version: mysql

Description:

php artisan octane:reload doesn’t reflect new changes for a symbolic link deployment. This happens for both swoole and roadrunner.

(Still under confirmation) Event with server roadrunner, I suspected that passing the config path directly #335 should have fixed it but now it seems like it will have the same issue.

Our current deployment uses deployer PHP that produces following dir structure.

Dir structure: Before release

current -> releases/112
releases
shared

Dir structure: After release

current -> releases/113 #symblink changed
releases
shared
## octane:reload here...

Upon symbolic link change, octane::reload doesn’t have any effect for the new changes. I think it refers to the previous deployment dir still and reload workers from there.

As an alternative, we are doing octane::stop ▶ symbolic link change ▶ octane::start. This of course is not a hot deployment. The other work around that we are now considering is rsync based deployment instead of symbolic link strategy.

Steps To Reproduce:

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Yeah I understand the limitations, I was curious if there were any plans to create a workaround for this, or a more elegant way to restart/reload octane with the least impact/downtime possible

Simply by deploying in another directory you can’t reload an application.

I personally do blue-green deployments. Work like charm.

  1. setup 2 services to run octane on 2 separate ports.
  2. have in your webserver an upstream pointing to them both.
  3. on deployment, reconfigure upstream to one of them, upgrade the other, if healthy, change upstream to it, continue with the first one, reconfigure upstream.

Nginx and Apache support reload of configuration with zero downtime.

Personally I scripted this in Ansible, works like a charm and takes like 10s full deployment, with zero downtime.

I suggest similar approach with your favorite automation tool for provisioning.

Thanks for confirming @thyseus

I have done following 2 confirmations.

  1. octane::reload doesn’t work on a symbolic link deployment.
  2. For a non symbolic link deployment, octane::reload doesn’t work when opcache is enabled.

The swoole doc asks to refresh it opcache

APC/OpCache and hot reloading stat in APC/OpCache has to be enabled for code reloading Refresh OpCache with apc_clear_cache() or opcache_reset() if necessary

I tried with adding opcache refresh step as octane::reload -> then -> opcache_refresh() but that didn’t help. As a solution for now, I have disabled the opcache.enable_cli => Off => Off.

I think, octane:reload cli doesn’t need to provide opcache refresh, as this is the responsibility of the deployment strategy.

Question: I don’t know for sure if opcache is suggested or will benefit when using Octane.

To @thyseus

'system:restart-supervisor', is not a good option as this causes downtime. Instead a simple rsync strategy works better.

set('app_path', '/somewhere/app');
//tasks
    'deploy:symlink',
    'deploy:rsync',
    'deploy:reload-octane',

task('deploy:rsync', function () {
    run("rsync -a  --exclude 'storage' --delete {{current_path}}/ {{app_path}}");
});

task('deploy:reload-octane', function () {
    run('php {{app_path}}/artisan octane:reload');
});

@HassanZahirnia you won’d be able to escape this on using octane in same host. Reason:

https://github.com/laravel/octane/blob/24ab7f9109bb39ddcd76f51e6df1d4a7578366c3/src/Swoole/ServerProcessInspector.php#L21

Looks like similar to some other Laravel code, the implementation is for only one instance only.

It does work when you do this in separate containers or servers.

I mentioned to create a separate service, and did not encounter the issue as I am using containers (with Podman) and I setup a service unit for each process I run, it is isolated, allows me to scale on many hosts or on same hosts without issues.

I can give you a tip until Octane, and many other Laravel things are refactored to be truly scalable and cloud oriented:

Do 2 deployments for 1 version and your storage files (only for files, as I hope you put sessions in the database, especially if you want to scale horizontally)

The scenario above is possible this way on same host, without containers.

On deployment, start with instance 1, continue with instance 2.

Hi @gemini133 For centos7 No it doesn’t. I tried with both road runner and swoole. I ended up using octane:stop and octane:start, and before doing that. taking server off the load balancer. This is ok, it just adds around an extra minute per server to the deployer.