@@ -9,172 +9,147 @@
# Introduction
-This package allows you to use Google Cloud Tasks as your queue driver.
+This package allows Google Cloud Tasks to be used as the queue driver.
-# How it works
-
-Using Cloud Tasks as a Laravel queue driver is fundamentally different than other Laravel queue drivers, like Redis.
-
-Typically a Laravel queue has a worker that listens to incoming jobs using the `queue:work` / `queue:listen` command.
-With Cloud Tasks, this is not the case. Instead, Cloud Tasks will schedule the job for you and make an HTTP request to your application with the job payload. There is no need to run a `queue:work/listen` command.
-
-For more information on how to configure the Cloud Tasks queue, read the next section [Configuring the queue](#configuring-the-queue)
-
-This package uses the HTTP request handler and doesn't support AppEngine. But feel free to contribute!
+
+
+
-# Requirements
+
+
+ Requirements
+
-This package requires Laravel 5.6 or higher.
+
+ This package requires Laravel 6 or higher and supports MySQL 8 and PostgreSQL 14. Might support older database versions too, but package hasn't been tested for it.
Please check the table below for supported Laravel and PHP versions:
|Laravel Version| PHP Version |
-|---|---|
-| 5.6 | 7.2 or 7.3 or 7.4
-| 5.7 | 7.2 or 7.3 or 7.4
-| 5.8 | 7.2 or 7.3 or 7.4
-| 6.x | 7.2 or 7.3 or 7.4 or 8.0
-| 7.x | 7.2 or 7.3 or 7.4 or 8.0
-| 8.x | 7.3 or 7.4 or 8.0 or 8.1
+ |---|---|
+| 6.x | 7.4 or 8.0
+| 7.x | 7.4 or 8.0
+| 8.x | 7.4 or 8.0 or 8.1
| 9.x | 8.0 or 8.1
+
+
+ Installation
+
-# Installation
-
-(1) Require the package using Composer
-
-```bash
-composer require stackkit/laravel-google-cloud-tasks-queue
-```
-
+ Require the package using Composer
-[Official documentation - Creating Cloud Tasks queues](https://cloud.google.com/tasks/docs/creating-queues)
+ ```console
+ composer require stackkit/laravel-google-cloud-tasks-queue
+ ```
-(2) Add a new queue connection to `config/queue.php`
+ Add a new queue connection to `config/queue.php`
-```
-'cloudtasks' => [
- 'driver' => 'cloudtasks',
- 'project' => env('STACKKIT_CLOUD_TASKS_PROJECT', ''),
- 'location' => env('STACKKIT_CLOUD_TASKS_LOCATION', ''),
- 'handler' => env('STACKKIT_CLOUD_TASKS_HANDLER', ''),
- 'queue' => env('STACKKIT_CLOUD_TASKS_QUEUE', 'default'),
- 'service_account_email' => env('STACKKIT_CLOUD_TASKS_SERVICE_EMAIL', ''),
-],
-```
+ ```php
+ 'cloudtasks' => [
+ 'driver' => 'cloudtasks',
+ 'project' => env('STACKKIT_CLOUD_TASKS_PROJECT', ''),
+ 'location' => env('STACKKIT_CLOUD_TASKS_LOCATION', ''),
+ 'handler' => env('STACKKIT_CLOUD_TASKS_HANDLER', ''),
+ 'queue' => env('STACKKIT_CLOUD_TASKS_QUEUE', 'default'),
+ 'service_account_email' => env('STACKKIT_CLOUD_TASKS_SERVICE_EMAIL', ''),
+ ],
+ ```
-(3) Update the `QUEUE_CONNECTION` environment variable
+Update the `QUEUE_CONNECTION` environment variable
-```
-QUEUE_CONNECTION=cloudtasks
-```
-
-(4) [Laravel ^8.0 and above only] configure failed tasks to use the `database-uuids` driver in `config/queue.php`
-
-```
-'failed' => [
- 'database' => env('DB_CONNECTION', 'mysql'),
- 'table' => 'failed_jobs',
- 'driver' => 'database-uuids',
-],
-```
-
-(5) Create a new Cloud Tasks queue using `gcloud`
-
-````bash
-gcloud tasks queues create [QUEUE_ID]
-````
+ ```dotenv
+ QUEUE_CONNECTION=cloudtasks
+ ```
Now that the package is installed, the final step is to set the correct environment variables.
Please check the table below on what the values mean and what their value should be.
-|Environment variable|Description|Example
-|---|---|---
-|`STACKKIT_CLOUD_TASKS_PROJECT`|The project your queue belongs to.|`my-project`
-|`STACKKIT_CLOUD_TASKS_LOCATION`|The region where the AppEngine is hosted|`europe-west6`
-|`STACKKIT_CLOUD_TASKS_HANDLER`|The URL that Cloud Tasks will call to process a job. This should be the URL to your Laravel app with the `handle-task` path added|`https://.com/handle-task`
-|`STACKKIT_CLOUD_TASKS_QUEUE`|The queue a job will be added to|`emails`
-|`STACKKIT_CLOUD_TASKS_SERVICE_EMAIL`|The email address of the AppEngine service account. Important, it should have the *Cloud Tasks Enqueuer* role. This is used for securing the handler.|`my-service-account@appspot.gserviceaccount.com`
-
-# Authentication
-
-Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable with a path to the credentials file.
-
-More info: https://cloud.google.com/docs/authentication/production
-
-## Service Account Roles
-
-If you're not using your master service account (which has all abilities), you must add the following roles to make it works:
-1. App Engine Viewer
-2. Cloud Tasks Enqueuer
-3. Cloud Tasks Viewer
-4. Cloud Tasks Task Deleter
-5. Service Account User
-
-# Configuring the queue
-
-When you first create a queue using `gcloud tasks queues create`, the default settings will look something like this:
-
-```
-rateLimits:
- maxBurstSize: 100
- maxConcurrentDispatches: 1000
- maxDispatchesPerSecond: 500.0
-retryConfig:
- maxAttempts: 100
- maxBackoff: 3600s
- maxDoublings: 16
- minBackoff: 0.100s
-```
-
-## Configurable settings
-
-### maxBurstSize
+| Environment variable | Description |Example
+--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---
+| `STACKKIT_CLOUD_TASKS_PROJECT` | The project your queue belongs to. |`my-project`
+| `STACKKIT_CLOUD_TASKS_LOCATION` | The region where the project is hosted |`europe-west6`
+| `STACKKIT_CLOUD_TASKS_QUEUE` | The default queue a job will be added to |`emails`
+| `STACKKIT_CLOUD_TASKS_SERVICE_EMAIL` | The email address of the service account. Important, it should have the correct roles. See the section below which roles. |`my-service-account@appspot.gserviceaccount.com`
+| `STACKKIT_CLOUD_TASKS_HANDLER` (optional) | The URL that Cloud Tasks will call to process a job. This should be the URL to your Laravel app. By default we will use the URL that dispatched the job. |`https://.com`
+
+
+
+ How it works
+
+
+ Using Cloud Tasks as a Laravel queue driver is fundamentally different than other Laravel queue drivers, like Redis.
-Max burst size limits how fast tasks in queue are processed when many tasks are in the queue and the rate is high.
-
-### maxConcurrentDispatches
+Typically a Laravel queue has a worker that listens to incoming jobs using the `queue:work` / `queue:listen` command.
+With Cloud Tasks, this is not the case. Instead, Cloud Tasks will schedule the job for you and make an HTTP request to your application with the job payload. There is no need to run a `queue:work/listen` command.
+
+
+ Dashboard (beta)
+
+ The package comes with a beautiful dashboard that can be used to monitor all queued jobs.
-The maximum number of concurrent tasks that Cloud Tasks allows to be dispatched for this queue
-### maxDispatchesPerSecond
+
-The maximum rate at which tasks are dispatched from this queue.
+ ---
-### maxAttempts
+_Experimental_
-Number of attempts per task. Cloud Tasks will attempt the task max_attempts times (that is, if the first attempt fails, then there will be max_attempts - 1 retries). Must be >= -1.|
+The dashboard works by storing all outgoing tasks in a database table. When Cloud Tasks calls the application and this
+package handles the task, we will automatically update the tasks' status, attempts
+and possible errors.
-### maxBackoff
+There is probably a (small) performance penalty because each task dispatch and handling does extra database read and writes.
+Also, the dashboard has not been tested with high throughput queues.
-A task will be scheduled for retry between min_backoff and max_backoff duration after it fails
+ ---
-### maxDoublings
-The time between retries will double max_doublings times.
+To make use of it, enable it through the `.env` file:
-A task's retry interval starts at min_backoff, then doubles max_doublings times, then increases linearly, and finally retries retries at intervals of max_backoff up to max_attempts times.
-
-For example, if min_backoff is 10s, max_backoff is 300s, and max_doublings is 3, then the a task will first be retried in 10s. The retry interval will double three times, and then increase linearly by 2^3 * 10s. Finally, the task will retry at intervals of max_backoff until the task has been attempted max_attempts times. Thus, the requests will retry at 10s, 20s, 40s, 80s, 160s, 240s, 300s, 300s, ....
+ ```dotenv
+ STACKKIT_CLOUD_TASKS_DASHBOARD_ENABLED=true
+ STACKKIT_CLOUD_TASKS_DASHBOARD_PASSWORD=MySecretLoginPasswordPleaseChangeThis
+ ```
-## Recommended settings for Laravel
+Then publish its assets and migrations:
-To simulate a single `queue:work/queue:listen` process, simply set the `maxConcurrentDispatches` to 1:
+ ```console
+ php artisan vendor:publish --tag=cloud-tasks
+ php artisan migrate
+ ```
-```
-gcloud tasks queues update [QUEUE_ID] --max-concurrent-dispatches=1
-```
+The dashboard is accessible at the URI: /cloud-tasks
-More information on configuring queues:
+
+
+ Authentication
+
-https://cloud.google.com/tasks/docs/configuring-queues
+Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable with a path to the credentials file.
-# Security
+More info: https://cloud.google.com/docs/authentication/production
-The job handler requires each request to have an OpenID token. In the installation step we set the service account email, and with that service account, Cloud Tasks will generate an OpenID token and send it along with the job payload to the handler.
+If you're not using your master service account (which has all abilities), you must add the following roles to make it works:
+1. App Engine Viewer
+2. Cloud Tasks Enqueuer
+3. Cloud Tasks Viewer
+4. Cloud Tasks Task Deleter
+5. Service Account User
+
+
+ Security
+
+ The job handler requires each request to have an OpenID token. In the installation step we set the service account email, and with that service account, Cloud Tasks will generate an OpenID token and send it along with the job payload to the handler.
This package verifies that the token is digitally signed by Google. Only Google Tasks will be able to call your handler.
More information about OpenID Connect:
https://developers.google.com/identity/protocols/oauth2/openid-connect
+
+
+ Upgrading
+
+ Read [UPGRADING.MD](UPGRADING.md) on how to update versions.
+
diff --git a/UPGRADING.md b/UPGRADING.md
new file mode 100644
index 0000000..93d0a71
--- /dev/null
+++ b/UPGRADING.md
@@ -0,0 +1,18 @@
+# From 2.x to 3.x
+
+PHP 7.2 and 7.3, and Laravel 5.x are no longer supported.
+
+## Update handler URL (Impact: high)
+
+The handler URL environment has been simplified. Please change it like this:
+
+```dotenv
+# Before
+STACKKIT_CLOUD_TASKS_HANDLER=https://my-app/handle-task
+# After
+STACKKIT_CLOUD_TASKS_HANDLER=https://my-app
+```
+
+It's also allowed to remove this variable entirely in 3.x: The package will automatically use the application URL if the `STACKKIT_CLOUD_TASKS_HANDLER`
+environment is not present. If you omit it, please ensure the [trusted proxy](https://laravel.com/docs/9.x/requests#configuring-trusted-proxies) have been configured
+in your application. Otherwise, you might run into weird issues. :-)
diff --git a/assets/cloud-tasks-home.png b/assets/cloud-tasks-home.png
new file mode 100644
index 0000000..4ed2802
Binary files /dev/null and b/assets/cloud-tasks-home.png differ
diff --git a/assets/dashboard.png b/assets/dashboard.png
new file mode 100644
index 0000000..0051f17
Binary files /dev/null and b/assets/dashboard.png differ
diff --git a/logo.png b/assets/logo.png
similarity index 100%
rename from logo.png
rename to assets/logo.png
diff --git a/composer.json b/composer.json
index 5683ac1..c01c313 100644
--- a/composer.json
+++ b/composer.json
@@ -9,13 +9,15 @@
],
"require": {
"ext-json": "*",
- "google/cloud-tasks": "^v1.9",
- "firebase/php-jwt": "^5.5",
- "phpseclib/phpseclib": "~2.0"
+ "phpseclib/phpseclib": "~2.0",
+ "google/cloud-tasks": "^1.10",
+ "thecodingmachine/safe": "^1.0|^2.0"
},
"require-dev": {
- "mockery/mockery": "^1.2",
- "orchestra/testbench": "^3.5 || ^3.6 || ^3.7 || ^3.8 || ^4.0 || ^5.0"
+ "orchestra/testbench": "^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "nunomaduro/larastan": "^1.0 || ^2.0",
+ "thecodingmachine/phpstan-safe-rule": "^1.2",
+ "laravel/legacy-factories": "^1.3"
},
"autoload": {
"psr-4": {
@@ -24,7 +26,8 @@
},
"autoload-dev": {
"psr-4": {
- "Tests\\": "tests/"
+ "Tests\\": "tests/",
+ "Factories\\": "factories/"
}
},
"extra": {
diff --git a/config/cloud-tasks.php b/config/cloud-tasks.php
new file mode 100644
index 0000000..c8cbdca
--- /dev/null
+++ b/config/cloud-tasks.php
@@ -0,0 +1,10 @@
+ [
+ 'enabled' => env('STACKKIT_CLOUD_TASKS_DASHBOARD_ENABLED', false),
+ 'password' => env('STACKKIT_CLOUD_TASKS_DASHBOARD_PASSWORD', 'MyPassword1!')
+ ],
+];
diff --git a/dashboard/.env.production b/dashboard/.env.production
new file mode 100644
index 0000000..292a14c
--- /dev/null
+++ b/dashboard/.env.production
@@ -0,0 +1 @@
+VITE_API_URL=
diff --git a/dashboard/.gitignore b/dashboard/.gitignore
new file mode 100644
index 0000000..a84704d
--- /dev/null
+++ b/dashboard/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+.DS_Store
+dist-ssr
+*.local
\ No newline at end of file
diff --git a/dashboard/.prettierignore b/dashboard/.prettierignore
new file mode 100644
index 0000000..85dd8c4
--- /dev/null
+++ b/dashboard/.prettierignore
@@ -0,0 +1,6 @@
+# Ignore artifacts:
+build
+coverage
+.vscode
+node_modules
+.idea
diff --git a/dashboard/.prettierrc.js b/dashboard/.prettierrc.js
new file mode 100644
index 0000000..0614ee7
--- /dev/null
+++ b/dashboard/.prettierrc.js
@@ -0,0 +1,6 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: false,
+ singleQuote: true,
+}
diff --git a/dashboard/.prettierrc.json b/dashboard/.prettierrc.json
new file mode 100644
index 0000000..b2095be
--- /dev/null
+++ b/dashboard/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/dashboard/README.md b/dashboard/README.md
new file mode 100644
index 0000000..c0793a8
--- /dev/null
+++ b/dashboard/README.md
@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `
+
+
+
+
+
+
+
+