How to correctly queue image manipulation in laravel with beanstalkd while uploading to Amazon S3? -
i'm doing tests laravel loading images amazon s3 , queuing image manipulation beanstalkd. please note testing.
here implementation:
// routes.php
route::post('/', function() { $validator = validator::make(input::all(), array( 'title' => 'required', 'file' => 'required|mimes:jpeg,jpg,png', )); if( $validator->fails() ) { return redirect::to('/'); } // upload file $file = input::file('file'); $now = new datetime; $hash = md5( $file->getclientoriginalname().$now->format('y-m-d h:i:s') ); $key = $hash.'.'.$file->getclientoriginalextension(); $s3 = aws::createclient('s3'); $s3->putobject(array( 'bucket' => 'bellated', 'key' => $key, 'sourcefile' => $file->getrealpath(), 'contenttype' => $file->getclientmimetype(), )); // create job queue::push('\proc\worker\imageprocessor', array( 'bucket' => 'bellated', 'hash' => $hash, 'key' => $key, 'ext' => $file->getclientoriginalextension(), 'mimetype' => $file->getclientmimetype(), )); log::info('queue processed'); return redirect::to('/complete'); });
// image processor
<?php namespace proc\worker; use imagine\gd\imagine; use imagine\image\box; class imageprocessor { protected $width; protected $height; protected $image; public function fire($job, $data) { $s3 = \aws::createclient('s3'); try { $response = $s3->getobject(array( 'bucket' => $data['bucket'], 'key' => $data['key'], )); } catch (exception $e) { return; } $imagine = new imagine(); $image = $imagine->load( (string)$response->get('body') ); $size = new box(100, 100); $thumb = $image->thumbnail($size); $s3->putobject(array( 'bucket' => 'bellated', 'key' => $data['hash'].'_100x100.'.$data['ext'], 'body' => $thumb->get($data['ext']), 'contenttype' => $data['mimetype'], )); } }
when have 'sync' queue - works fine , both images (original , resized) in amazon, after switched 'beanstlakd' , run php artisan queue:listen keep getting error:
next exception 'aws\s3\exception\s3exception' message 'error executing "getobject" on "https://s3.eu-central-1.amazonaws.com/bellated/cd05ec14f7a19047828d7ed79d192ee3.jpg"; aws http error: client error: 404 nosuchkey (client): specified key not exist. - <?xml version="1.0" encoding="utf-8"?> <error> <code>nosuchkey</code> <message>the specified key not exist.</message> <key>cd05ec14f7a19047828d7ed79d192ee3.jpg</key> <requestid>9390ad2904820c3e</requestid> <hostid> nzk1ivzn3bs6xy0s/tge+a7yozgkkcclpudobkuws2zmi8lxugfi5jpkqwckwchcw6tgw7jyvge= </hostid> </error>' in /home/vagrant/code/laravel/vendor/aws/aws-sdk-php/src/wrappedhttphandler.php:152
any ideas on might causing or how proceed on this?
it looks setting s3 key file name might causeing grief.
$s3->putobject(array( 'bucket' => 'bellated', 'key' => $data['hash'].'_100x100.'.$data['ext'], 'body' => $thumb->get($data['ext']), 'contenttype' => $data['mimetype'], ));
the error makes me think this.
client error: 404 nosuchkey (client): specified key not exist. - <key>cd05ec14f7a19047828d7ed79d192ee3.jpg</key>
in general, looks doing hard way. not sure how make code work, laravel lot of trying right out of box.
here how have done trying do.
you need set environment.
.env
s3_key=mykeymykeymykeymykey s3_secret=mysecretmysecretmysecretmysecretmysecret s3_region=us-east-1 s3_bucket=bucketname
config/filesystem.php
<?php return [ 'default' => 'local', 'cloud' => 's3', 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path().'/app', ], 's3' => [ 'driver' => 's3', 'key' => env('s3_key'), 'secret' => env('s3_secret'), 'region' => env('s3_region'), 'bucket' => env('s3_bucket'), ], ], ];
routes.php quick test
route::get('s3',function(){ $success = storage::disk('s3')->put('hello.txt','hello'); return ($success)?'yeay!':'boo hoo'; });
i know text file same.
how handle queueing using laravel's job (it use command).
at terminal type make app/jobs/newjob.php file.
php artisan make:job newjob --queued
set job this.
newjob.php
<?php namespace app\jobs; use ...; class newjob extends job implements selfhandling, shouldqueue { public $content; public $path; use interactswithqueue, serializesmodels; public function __construct($content, $path) { $this->content = $content; $this->path = $path; } public function handle() { storage::disk('s3')->put($this->path,$this->content) } }
and controller this
<?php namespace app\http\controllers; use ...; class imagecontroller extends controller { public function sendimage($content, $path) { $this->dispatch(new newjob($content, $path)); } }
Comments
Post a Comment