From 9b5d75cfa7a9792b5830affcb4c4a3a2355ae0ad Mon Sep 17 00:00:00 2001 From: Benjamin Friedman Date: Sun, 12 Nov 2017 16:41:24 -0800 Subject: [PATCH 1/2] Adds jobs to ParseCloud --- README.md | 16 ++++++++ src/Parse/ParseCloud.php | 53 +++++++++++++++++++++++++ tests/Parse/ParseCloudTest.php | 72 ++++++++++++++++++++++++++++++++++ tests/cloudcode/cloud/main.js | 18 +++++++++ 4 files changed, 159 insertions(+) diff --git a/README.md b/README.md index f1c852b4..919f5c5b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ from your PHP app or script. Designed to work with the self-hosted Parse Server - [Queries](#queries) - [Relative Time](#relative-time) - [Cloud Functions](#cloud-functions) + - [Cloud Jobs](#cloud-jobs) - [Analytics](#analytics) - [Files](#files) - [Push Notifications](#push) @@ -358,6 +359,21 @@ Directly call server-side cloud coud functions and get their results. $results = ParseCloud::run("aCloudFunction", array("from" => "php")); ``` +### Cloud Jobs + +Like cloud functions, cloud jobs allow you to run code server-side but in an asynchronous fashion. +Instead of waiting for execution to complete you are immediately returned an id for tracking the job's progress. +You can use this id to see the current information on a job and whether it has completed. +```php +// start job +$jobStatusId = ParseCloud::startJob('MyCloudJob', array("startedBy" => "me!")); + +// get job status, a ParseObject! +$jobStatus = ParseCloud::getJobStatus($jobStatusId); +$status = $jobStatus->get('status'); // failed / succeeded when done + +``` + ### Analytics A specialized Parse Object built purposely to make analytics easy. diff --git a/src/Parse/ParseCloud.php b/src/Parse/ParseCloud.php index c6805892..af1032f8 100644 --- a/src/Parse/ParseCloud.php +++ b/src/Parse/ParseCloud.php @@ -38,4 +38,57 @@ public static function run($name, $data = [], $useMasterKey = false) return ParseClient::_decode($response['result']); } + + /** + * Gets data for the current set of cloud jobs + * + * @return array + */ + public static function getJobsData() + { + $response = ParseClient::_request( + 'GET', + 'cloud_code/jobs/data', + null, + null, + true + ); + + return ParseClient::_decode($response); + } + + /** + * Starts a given cloud job, which will process asynchronously + * + * @param string $jobName Name of job to run + * @param array $data Parameters to pass + * @return string Id for tracking job status + */ + public static function startJob($jobName, $data = []) + { + $response = ParseClient::_request( + 'POST', + 'jobs/'.$jobName, + null, + json_encode(ParseClient::_encode($data, false)), + true, + false, + 'application/json', + true + ); + + return ParseClient::_decode($response)['_headers']['X-Parse-Job-Status-Id']; + } + + /** + * Gets job status by id + * + * @param string $jobStatusId Id of the job status to return + * @return array|ParseObject + */ + public static function getJobStatus($jobStatusId) + { + $query = new ParseQuery('_JobStatus'); + return $query->get($jobStatusId, true); + } } diff --git a/tests/Parse/ParseCloudTest.php b/tests/Parse/ParseCloudTest.php index 0c362f72..41c21c35 100644 --- a/tests/Parse/ParseCloudTest.php +++ b/tests/Parse/ParseCloudTest.php @@ -109,4 +109,76 @@ public function testUnknownFunctionFailure() ); ParseCloud::run('unknown_function', $params); } + + /** + * @group cloud-code-jobs + */ + public function testGetJobsData() + { + $jobsData = ParseCloud::getJobsData(); + $this->assertNotNull($jobsData['jobs']); + $this->assertNotNull($jobsData['in_use']); + $this->assertEquals(0, count($jobsData['in_use'])); + $this->assertEquals(3, count($jobsData['jobs'])); + } + + /** + * @group cloud-code-jobs + */ + public function testRunJob() + { + $jobStatusId = ParseCloud::startJob('CloudJob1', [ + 'startedBy' => 'Monty Python' + ]); + $this->assertNotNull($jobStatusId); + + $jobStatus = ParseCloud::getJobStatus($jobStatusId); + $this->assertNotNull($jobStatus); + $this->assertEquals('succeeded', $jobStatus->get('status')); + $this->assertEquals('Monty Python', $jobStatus->get('params')['startedBy']); + } + + /** + * @group cloud-code-jobs + */ + public function testLongJob() + { + $jobStatusId = ParseCloud::startJob('CloudJob2'); + $jobStatus = ParseCloud::getJobStatus($jobStatusId); + $this->assertNotNull($jobStatus); + $this->assertEquals('running', $jobStatus->get('status')); + } + + /** + * @group cloud-code-jobs + */ + public function testBadJob() + { + $this->setExpectedException('Parse\ParseException', 'Invalid job.'); + ParseCloud::startJob('bad_job'); + } + + /** + * @group cloud-code-jobs + */ + public function testFailingJob() + { + $jobStatusId = ParseCloud::startJob('CloudJobFailing'); + $this->assertNotNull($jobStatusId); + + $jobStatus = ParseCloud::getJobStatus($jobStatusId); + $this->assertNotNull($jobStatus); + $this->assertEquals('failed', $jobStatus->get('status')); + $this->assertEquals('cloud job failed', $jobStatus->get('message')); + } + + /** + * @group cloud-code-jobs + */ + public function testGettingNotARealJobStatus() + { + $this->setExpectedException('Parse\ParseException', 'Object not found.'); + $jobStatus = ParseCloud::getJobStatus('not-a-real-job-status'); + $this->assertNull($jobStatus); + } } diff --git a/tests/cloudcode/cloud/main.js b/tests/cloudcode/cloud/main.js index 259b8834..3dea25cd 100644 --- a/tests/cloudcode/cloud/main.js +++ b/tests/cloudcode/cloud/main.js @@ -41,3 +41,21 @@ Parse.Cloud.define("foo", function(request, response) { response.error('invalid!'); } }); + +Parse.Cloud.job('CloudJob1', function(request, response) { + response.success({ + status: 'cloud job completed' + }); +}); + +Parse.Cloud.job('CloudJob2', function(request, response) { + setTimeout(function() { + response.success({ + status: 'cloud job completed' + }) + }, 3000); +}); + +Parse.Cloud.job('CloudJobFailing', function(request, response) { + response.error('cloud job failed'); +}); From a37e12fd6bbee29d6383e1315d90cbfa2d4dbce3 Mon Sep 17 00:00:00 2001 From: Benjamin Friedman Date: Sun, 12 Nov 2017 17:08:20 -0800 Subject: [PATCH 2/2] Update parse-server-test to 1.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17f2c2a6..60876fdb 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,6 @@ "license": "https://github.com/parse-community/parse-php-sdk/blob/master/LICENSE", "homepage": "https://github.com/montymxb/parse-server-test#readme", "dependencies": { - "parse-server-test": "1.3.3" + "parse-server-test": "1.3.4" } }