I am using Laravel 5
with php 5.5.9-1ubuntu4.14
and mysql 5.5.47
.
I have a multi-tenant environment with each tenant having a separate DB. So for every HTTP request, I set the appropriate DB connection in the BeforeMiddleware
like so
public function handle($request, Closure $next)
{
...
// Set the client DB name and fire it up as the new default DB connection
Config::set('database.connections.mysql_client.host', $db_host);
Config::set('database.connections.mysql_client.database', $db_database);
Config::set('database.connections.mysql_client.username', $db_username);
Config::set('database.connections.mysql_client.password', $db_password);
DB::setDefaultConnection('mysql_client');
...
}
This works correctly even for concurrent HTTP requests.
But now I want to add scheduled jobs to my application. These jobs will send notifications to users belonging to all tenants. So, I again need to connect to respective tenant Databases. But this connection won't be through an HTTP request. Let's say I have a CommunicationController
and a function inside it for sending notifications.
public function sendNotification()
{
...
DB::purge('mysql_client');//IMP
// Set the client DB name and fire it up as the new default DB connection
Config::set('database.connections.mysql_client.host', $db_host);
Config::set('database.connections.mysql_client.database', $db_database);
Config::set('database.connections.mysql_client.username', $db_username);
Config::set('database.connections.mysql_client.password', $db_password);
DB::setDefaultConnection('mysql_client');
...
}
This is where I set the Config
values. This function will be executed every minute through Laravel Scheduler
.
My questions are:
Config
parameters are being set in both, HTTP request as well as Scheduled job?As you notice i schedule the command on daily basis but there are number of schedule frequencies which you can assign to the tasks. If you wan to start the scheduler itself then you will have to add one cron job on server using the crontab -e command. Using this, Laravel command scheduler will be called by cron every minute.
The queue:workCommand Laravel includes an Artisan command that will start a queue worker and process new jobs as they are pushed onto the queue. You may run the worker using the queue:workArtisan command. Note that once the queue:workcommand has started, it will continue to run until it is manually stopped or you close your terminal:
However, laravel provides two powerful features in Job classes that can be leveraged to avoid concurrency attacks. First is the ShouldBeUnique interface. Implementing this interface on a job class tells laravel to ensure that only one instance of this job should be running at any given time.
Generally laravel cronjob is task scheding. it means it will work according scheduled time. If you want to schedule tasks that will be executed every day automatically that is very helpful for you. Laravel cronjob is reduce the manually working time.
According to the Laravel docs:
Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests.
Configuration values are set at run-time when you specifically call the Config::set
method so the value will be only valid for that current request and you'll never have any concurrency issues due to that.
Your second question is impossible as well. Even if your previous task was running a request on the database, the second/subsequent tasks will wait for locks if any to be release on the database. You should try to be sure you're not performing any queries that can lock for a long period on your DB by using multi-insert, sqldump (if you're performing large queries).. etc
Looking at Illuminate\Config\Repository
which is the implementation used for the Config
facade and specifically the set
method
public function set($key, $value = null)
{
if (is_array($key)) {
foreach ($key as $innerKey => $innerValue) {
Arr::set($this->items, $innerKey, $innerValue);
}
} else {
Arr::set($this->items, $key, $value);
}
}
you can be assured that the set is not an IO set (ie. to the filesystem) but an in-memory set. So the CLI scheduler command that runs every minute will run in its own context like every other http request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With