-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #263 from bowphp/feat-integrate-queue-adapters
Feat integrate queue adapters
- Loading branch information
Showing
18 changed files
with
554 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bow\Console\Command; | ||
|
||
use Bow\Console\Color; | ||
use Bow\Console\Generator; | ||
use Bow\Support\Str; | ||
|
||
class GenerateQueueCommand extends AbstractCommand | ||
{ | ||
/** | ||
* Generate session | ||
* | ||
* @return void | ||
*/ | ||
public function generate(): void | ||
{ | ||
$create_at = date("YmdHis"); | ||
$filename = sprintf("Version%s%sTable", $create_at, ucfirst(Str::camel('queue'))); | ||
|
||
$generator = new Generator( | ||
$this->setting->getMigrationDirectory(), | ||
$filename | ||
); | ||
|
||
$generator->write('model/queue', [ | ||
'className' => $filename | ||
]); | ||
|
||
echo Color::green('Queue migration created.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
use Bow\Database\Migration\Migration; | ||
use Bow\Database\Migration\SQLGenerator; | ||
|
||
class {className} extends Migration | ||
{ | ||
/** | ||
* Up Migration | ||
*/ | ||
public function up(): void | ||
{ | ||
$this->create("queues", function (SQLGenerator $table) { | ||
$table->addString('id', ["primary" => true]); | ||
$table->addString('queue'); | ||
$table->addText('payload'); | ||
$table->addInteger('attempts', ["default" => 3]); | ||
$table->addEnum('status', [ | ||
"size" => ["waiting", "processing", "reserved", "failed", "done"], | ||
"default" => "waiting", | ||
]); | ||
$table->addDatetime('avalaibled_at'); | ||
$table->addDatetime('reserved_at', ["nullable" => true, "default" => null]); | ||
$table->addDatetime('created_at'); | ||
}); | ||
} | ||
|
||
/** | ||
* Rollback migration | ||
*/ | ||
public function rollback(): void | ||
{ | ||
$this->dropIfExists("queues"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
<?php | ||
|
||
namespace Bow\Queue\Adapters; | ||
|
||
use Bow\Database\Database; | ||
use Bow\Database\QueryBuilder; | ||
use Bow\Queue\ProducerService; | ||
|
||
class DatabaseAdapter extends QueueAdapter | ||
{ | ||
/** | ||
* Define the instance Pheanstalk | ||
* | ||
* @var QueryBuilder | ||
*/ | ||
private QueryBuilder $table; | ||
|
||
/** | ||
* Configure Beanstalkd driver | ||
* | ||
* @param array $queue | ||
* @return mixed | ||
*/ | ||
public function configure(array $queue): DatabaseAdapter | ||
{ | ||
$this->table = Database::table($queue["table"] ?? "queue_jobs"); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Get the size of the queue. | ||
* | ||
* @param string $queue | ||
* @return int | ||
*/ | ||
public function size(?string $queue = null): int | ||
{ | ||
return $this->table | ||
->where("queue", $this->getQueue($queue)) | ||
->count(); | ||
} | ||
|
||
/** | ||
* Queue a job | ||
* | ||
* @param ProducerService $producer | ||
* @return QueueAdapter | ||
*/ | ||
public function push(ProducerService $producer): void | ||
{ | ||
$this->table->insert([ | ||
"id" => $this->generateId(), | ||
"queue" => $this->getQueue(), | ||
"payload" => base64_encode($this->serializeProducer($producer)), | ||
"attempts" => $this->tries, | ||
"status" => "waiting", | ||
"avalaibled_at" => date("Y-m-d H:i:s", time() + $producer->getDelay()), | ||
"reserved_at" => null, | ||
"created_at" => date("Y-m-d H:i:s"), | ||
]); | ||
} | ||
|
||
/** | ||
* Run the worker | ||
* | ||
* @param string|null $queue | ||
* @return mixed | ||
*/ | ||
public function run(string $queue = null): void | ||
{ | ||
// we want jobs from define queue only. | ||
$queue = $this->getQueue($queue); | ||
$queues = $this->table | ||
->where("queue", $queue) | ||
->whereIn("status", ["waiting", "reserved"]) | ||
->get(); | ||
|
||
if (count($queues) == 0) { | ||
$this->sleep($this->sleep ?? 5); | ||
return; | ||
} | ||
|
||
foreach ($queues as $job) { | ||
try { | ||
$producer = $this->unserializeProducer(base64_decode($job->payload)); | ||
if (strtotime($job->avalaibled_at) >= time()) { | ||
if (!is_null($job->reserved_at) && strtotime($job->reserved_at) < time()) { | ||
continue; | ||
} | ||
$this->table->where("id", $job->id)->update([ | ||
"status" => "processing", | ||
]); | ||
$this->execute($producer, $job); | ||
continue; | ||
} | ||
} catch (\Exception $e) { | ||
error_log($e->getMessage()); | ||
app('logger')->error($e->getMessage(), $e->getTrace()); | ||
cache("failed:job:" . $job->id, $job->payload); | ||
if (!isset($producer)) { | ||
$this->sleep(1); | ||
continue; | ||
} | ||
if ($producer->jobShouldBeDelete() || $job->attempts <= 0) { | ||
$this->table->where("id", $job->id)->delete(); | ||
$this->sleep(1); | ||
continue; | ||
} | ||
$this->table->where("id", $job->id)->update([ | ||
"status" => "reserved", | ||
"attempts" => $job->attempts - 1, | ||
"avalaibled_at" => date("Y-m-d H:i:s", time() + $producer->getDelay()), | ||
"reserved_at" => date("Y-m-d H:i:s", time() + $producer->getRetry()) | ||
]); | ||
$this->sleep(1); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Process the next job on the queue. | ||
* | ||
* @param ProducerService $producer | ||
* @param mixed $job | ||
*/ | ||
private function execute(ProducerService $producer, mixed $job) | ||
{ | ||
call_user_func([$producer, "process"]); | ||
$this->table->where("id", $job->id)->update([ | ||
"status" => "done" | ||
]); | ||
sleep($this->sleep ?? 5); | ||
} | ||
|
||
/** | ||
* Flush the queue table | ||
* | ||
* @param ?string $queue | ||
* @return void | ||
*/ | ||
public function flush(?string $queue = null): void | ||
{ | ||
if (is_null($queue)) { | ||
$this->table->truncate(); | ||
} else { | ||
$this->table->where("queue", $queue)->delete(); | ||
} | ||
} | ||
} |
Oops, something went wrong.