Multi tenancy email cronjob

How to configure and adapt Aimeos based shops as developer
Forum rules
Always add your Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
dev_podup
Posts: 15
Joined: 10 Aug 2023, 02:06

Multi tenancy email cronjob

Post by dev_podup » 21 Nov 2023, 08:49

Hello,

Version info:
Laravel - 8.x, PHP - 8.0, Aimeos - ~2023.07

I understand the order emails are sent using cronjob. But I have a multi-tenancy setup, what can I do to make the cronjob work for all tenant databases? So that it looks order status for all tenants and sends emails.

User avatar
aimeos
Administrator
Posts: 7895
Joined: 01 Jan 1970, 00:00

Re: Multi tenancy email cronjob

Post by aimeos » 22 Nov 2023, 12:50

The jobs will be executed for all active sites in a multi-tenancy setup automatically.

Additionally, you can restrict executing a job to specific sites by adding the site codes as last parameter, e.g.:

Code: Select all

php artisan aimeos:jobs order/email/payment "default site2"
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

dev_podup
Posts: 15
Joined: 10 Aug 2023, 02:06

Re: Multi tenancy email cronjob

Post by dev_podup » 24 Nov 2023, 10:58

Thanks for the reply. By multi-tenancy, I mean I have multiple tenant databases. All tenant databases can have a single or multi-shop setup. The cronjob only seems to work for the database set in the .env file. How can I make the cronjob loop over all tenant databases?

User avatar
aimeos
Administrator
Posts: 7895
Joined: 01 Jan 1970, 00:00

Re: Multi tenancy email cronjob

Post by aimeos » 26 Nov 2023, 09:22

If you have multiple databases, you also have multiple application instances. Then, you have to add the cronjobs for each application instance.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

dev_podup
Posts: 15
Joined: 10 Aug 2023, 02:06

Re: Multi tenancy email cronjob

Post by dev_podup » 27 Nov 2023, 07:00

I have a single application with multiple databases. Each database is set into config for use.

I am running the following code in a cron every minute.

Code: Select all

$allTenants = Tenant::all();
foreach ($allTenants as $key => $tenant) {
    
    config(['database.connections.user.database' => $databaseName]);
    config(['shop.resource.db.database' => $databaseName]);
    DB::purge('user');
    DB::reconnect('user');

    $sites = Site::select('code')->get();
    if (!empty($sites)) {
        $siteCodes = '';
        foreach ($sites as $index => $site) {
            $siteCodes .= $site->code;
            if ($index < count($sites) - 1) {
                $siteCodes .= ' ';
            }
        }

        Artisan::call('aimeos:customjobs', [
            'database' => $databaseName,
            'jobs' => 'order/export/csv order/email/delivery order/email/payment order/email/voucher order/service/delivery subscription/export/csv customer/email/account',
            'site' => $siteCodes,
        ]);
    }
}
And in the custom command,

Code: Select all

protected $signature = 'aimeos:customjobs
    {database : Tenant database name}
    {jobs : One or more job controller names like "admin/job customer/email/watch"}
    {site? : Site codes to execute the jobs for like "default unittest" (none for all)}
';

public function handle()
{
    $jobs = $this->argument('jobs');
    $jobs = !is_array($jobs) ? explode(' ', (string) $jobs) : $jobs;

    $fcn = function (\Aimeos\MShop\ContextIface $lcontext, \Aimeos\Bootstrap $aimeos) use ($jobs) {
        $jobfcn = function ($context, $aimeos, $jobname) {
            \Aimeos\Controller\Jobs::create($context, $aimeos, $jobname)->run();
        };

        $process = $lcontext->process();
        $site = $lcontext->locale()->getSiteItem()->getCode();

        foreach ($jobs as $jobname) {
            $this->info(sprintf('Executing Aimeos jobs "%s" for "%s"', $jobname, $site), 'v');
            $process->start($jobfcn, [$lcontext, $aimeos, $jobname], false);
        }

        $process->wait();
    };

    $tenantDb = $this->argument('database');
    config(['database.connections.mysql.database' => $tenantDb]);
    config(['shop.resource.db.database' => $tenantDb]);
    DB::purge('mysql');
    DB::reconnect('mysql');
    $this->exec($this->context(), $fcn, $this->argument('site'));
}
But it takes the first database in loop and works only for that, not working for other DBs. Any help is appreciated.

User avatar
aimeos
Administrator
Posts: 7895
Joined: 01 Jan 1970, 00:00

Re: Multi tenancy email cronjob

Post by aimeos » 01 Dec 2023, 12:07

Guess, the artisan command is executed in a separate process and your changed in-memory config isn't used then.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply