2016-01-09 17 views
7

Mam trudności z ustaleniem, co dokładnie dzieje się z moją aplikacją Laravel. Jest w pełni funkcjonalny lokalnie (Mac, php 5.5.26), więc testowałem aplikację na mojej cyfrowej kropli oceanicznej poprzez kuźnię (php 5.6.15).Laravel Queue Unserializing Issue

Używam this package do wysyłania powiadomień push do aplikacji z przodu, która pobiera moje api Laravel. Aby przyspieszyć wywoływanie api, delegowałem powiadomienia push do kolejek Laravel, które działają świetnie lokalnie, ale otrzymałem ten błąd, gdy testowałem na cyfrowym oceanie.

[2016-01-09 20:34:09] stage.ERROR: exception 'ErrorException' with message 'Erroneous data format for unserializing 'ArrayIterator'' in {path}/{project}/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php:74 

Używam sterownika bazy danych. Oto odcinkach wiersz pracy w moim lokalnym tabeli zatrudnienia bazy danych ...

{"job":"Illuminate\\Queue\\[email protected]","data":{"command":"O:28:\"App\\Jobs\\Push\\SendPushFollow\":4:{s:34:\"\u0000App\\Jobs\\Push\\SendPushFollow\u0000push\";O:27:\"App\\Helpers\\Push\\PushFollow\":5:{s:14:\"\u0000*\u0000ios_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";C:13:\"ArrayIterator\":21:{x:i:0;a:0:{};m:a:0:{}}}s:16:\"\u0000*\u0000android_count\";i:2;s:12:\"\u0000*\u0000ios_count\";i:0;s:18:\"\u0000*\u0000android_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";C:13:\"ArrayIterator\":953:{x:i:0;a:2:{s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";s:13:\"\u0000*\u0000parameters\";a:0:{}}s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";s:13:\"\u0000*\u0000parameters\";a:0:{}}};m:a:0:{}}}s:10:\"\u0000*\u0000message\";O:36:\"Sly\\NotificationPusher\\Model\\Message\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Message\u0000text\";s:32:\"John Smith is now following you!\";s:10:\"\u0000*\u0000options\";a:12:{s:5:\"badge\";i:1;s:5:\"sound\";s:12:\"example.aiff\";s:12:\"actionLocKey\";s:20:\"Action button title!\";s:6:\"locKey\";s:13:\"localized key\";s:7:\"locArgs\";a:2:{i:0;s:14:\"localized args\";i:1;s:14:\"localized args\";}s:11:\"launchImage\";s:9:\"image.jpg\";s:5:\"title\";s:21:\"InMyBag: New Follower\";s:6:\"custom\";a:0:{}s:5:\"notId\";i:7;s:5:\"style\";s:5:\"inbox\";s:8:\"ledColor\";a:4:{i:0;i:0;i:1;i:0;i:2;i:255;i:3;i:0;}s:16:\"vibrationPattern\";a:3:{i:0;i:500;i:1;i:250;i:2;i:500;}}}}s:5:\"queue\";N;s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}} 

i tu jest wejście wiersz z tabeli serwera ...

{"job":"Illuminate\\Queue\\[email protected]","data":{"command":"O:28:\"App\\Jobs\\Push\\SendPushFollow\":4:{s:34:\"\u0000App\\Jobs\\Push\\SendPushFollow\u0000push\";O:27:\"App\\Helpers\\Push\\PushFollow\":5:{s:14:\"\u0000*\u0000ios_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";O:13:\"ArrayIterator\":0:{}}s:16:\"\u0000*\u0000android_count\";i:2;s:12:\"\u0000*\u0000ios_count\";i:0;s:18:\"\u0000*\u0000android_devices\";O:50:\"Sly\\NotificationPusher\\Collection\\DeviceCollection\":1:{s:7:\"\u0000*\u0000coll\";O:13:\"ArrayIterator\":2:{s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bGCWGMQlh6kMYVVPUjnkDKtgLmYBiHxv1WY4r3zPjmXO3C0_UcvBCoOWkiiiC8lBc4JRILBDo29K0BtGNQKKQAA46tCvJocklTp3u7_x4q8Nz9CubNuqJN_OaMRBys_HWUqNXPLzIbodjEHV_bTc-CUKurnRQ\";s:13:\"\u0000*\u0000parameters\";a:0:{}}s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";O:35:\"Sly\\NotificationPusher\\Model\\Device\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Device\u0000token\";s:162:\"APA91bEUPnqR3t8KDhE0YTsc_HnkoxFvw4WyUpRxISm2A_2Ep7orCySVKsh2oRVSQTVOhSZS_yYjP7gup5vEnuwz2JPXcxHCc19P98E2QVNyjhTP_NvDkcfkogVIHAHpgelyGRuvm8aQ-SAs9uirxd3iBHPlZb16zA\";s:13:\"\u0000*\u0000parameters\";a:0:{}}}}s:10:\"\u0000*\u0000message\";O:36:\"Sly\\NotificationPusher\\Model\\Message\":2:{s:42:\"\u0000Sly\\NotificationPusher\\Model\\Message\u0000text\";s:32:\"John Smith is now following you!\";s:10:\"\u0000*\u0000options\";a:12:{s:5:\"badge\";i:1;s:5:\"sound\";s:12:\"example.aiff\";s:12:\"actionLocKey\";s:20:\"Action button title!\";s:6:\"locKey\";s:13:\"localized key\";s:7:\"locArgs\";a:2:{i:0;s:14:\"localized args\";i:1;s:14:\"localized args\";}s:11:\"launchImage\";s:9:\"image.jpg\";s:5:\"title\";s:21:\"InMyBag: New Follower\";s:6:\"custom\";a:0:{}s:5:\"notId\";i:10;s:5:\"style\";s:5:\"inbox\";s:8:\"ledColor\";a:4:{i:0;i:0;i:1;i:0;i:2;i:255;i:3;i:0;}s:16:\"vibrationPattern\";a:3:{i:0;i:500;i:1;i:250;i:2;i:500;}}}}s:5:\"queue\";N;s:5:\"delay\";N;s:6:\"\u0000*\u0000job\";N;}"}} 

ja prowadził DIF tekstu online, i okazało się, że zserializowana część danych tego obiektu typu blob ma kilka różnic, które występują (jak wskazano w dziennikach błędów) w części ArrayIterator. Wygląda na to, że różnica wynika z tego, że sposób serializacji obiektu PushNotification :: DeviceCollection różni się między moją maszyną lokalną a serwerem. W moich testach trafiłem punkt końcowy API lokalnie i na serwerze z tymi samymi danymi POST, aby upewnić się, że wynik serializacji powinien być taki sam, ale tak nie jest.

Nie jestem pewien, jak to naprawić. Nie wiem, czy jest to technicznie błąd związany z pakietem PushNotification (nie widziałem żadnych zgłoszeń błędów związanych z tym problemem), czy jest to po prostu coś innego, co glosuję.

Również na marginesie, używam kolejnej kolejki do wysyłania zdarzeń KeenIO przy użyciu podobnej struktury klasowej jak ta struktura Push i nie ma ona żadnych problemów, więc naprawdę czuję, że to musi być problem z PushNotification pakiet jakoś ... Wszelkie myśli?


SOLVED

Tak więc okazuje się, że to był problem z wersją PHP. Mój serwer działał 5.6, a kiedy zrobiłem kolejną kroplę na PHP 7.0 i sklonowałem serwer, wszystko zaczęło działać. Zostawiłem oryginalny serwer i mogłem działać jako procesor kolejki dla powiadomień push przy użyciu beanstalkd i działało jak mistrz.


EDIT

Używam przełożonego do uruchomienia kolejki: polecenie pracy. Mam biegać

php artisan queue:restart 

i zrobiłem pewien, że proces rzemieślnik jest całkowicie zatrzymany, gdy uruchomiony nowy test wydając polecenie kill poprzez linię poleceń. Znowu pracownik kolejki nie ma problemów z moimi zadaniami KeenIO na serwerze, tylko z zadaniami PushNotification.

Oto klasa praca:

<?php namespace App\Jobs\Push; 

use Illuminate\Queue\SerializesModels; 
use Illuminate\Queue\InteractsWithQueue; 
use Illuminate\Contracts\Bus\SelfHandling; 
use Illuminate\Contracts\Queue\ShouldQueue; 
use App\Jobs\SendPushEvent; 
use App\Helpers\Push\PushFollow; 

class SendPushFollow extends SendPushEvent implements SelfHandling, ShouldQueue { 
    use InteractsWithQueue, SerializesModels; 
    private $push; 
    /** 
    * Create a new job instance. 
    * 
    * @return void 
    */ 
    public function __construct($follower, $followee) 
    { 
     $this->push = new PushFollow($follower, $followee); 
    } 

    /** 
    * Execute the job. 
    * 
    * @return void 
    */ 
    public function handle(){ 
     $this->push->send(); 
    } 
} 

A oto klasa PushFollow który ma wszystkie logiki PushNotification w nim.

<?php namespace App\Helpers\Push; 

use PushNotification; 
use App\Helpers\Push\Push; 
use Log; 

class PushFollow extends Push { 
    /** 
    * This builds the default notification. 
    * @param array $data the passed in data array 
    * @param [type] $type android or iOS 
    */ 
    public function __construct ($follower, $followee) { 
     $_ios_devices = []; 
     $_android_devices = []; 
     $this->ios_count = 0; 
     $this->android_count = 0; 

     foreach($followee->devices as $_device){ 
      if($_device->platform == "ios"){ 
       $_ios_devices[] = PushNotification::Device($_device->identifier); 
       $this->ios_count++; 
      } elseif ($_device->platform == "android") { 
       $_android_devices[] = PushNotification::Device($_device->identifier); 
       $this->android_count++; 
      } 
     } 

     Log::info('FINISHED BUILDING THE LISTS!!!'); 

     $this->ios_devices = PushNotification::DeviceCollection($_ios_devices); 
     $this->android_devices = PushNotification::DeviceCollection($_android_devices); 

     Log::info('SET THE DEVICE COLLECTIONS'); 

     $this->message = PushNotification::Message($follower->profile->name.' is now following you!',[ 
      'badge' => 1, 
      'sound' => 'example.aiff', 
      'actionLocKey' => 'Action button title!', 
      'locKey' => 'localized key', 
      'locArgs' => array(
       'localized args', 
       'localized args', 
      ), 
      'launchImage' => 'image.jpg', 
      'title' => env('APP_NAME').': New Follower', 
      'custom' => [], 
      'notId' => rand(1, 20), 
      'style' => 'inbox', 
      /* 
      'actions' => [ 
       ['icon' => "emailGuests", 'title' => "EMAIL GUESTS", 'callback' => "app.emailGuests"], 
       [ 'icon' => "snooze", 'title' => "SNOOZE", 'callback' => "app.snooze"], 
      ], 
      */ 
      'ledColor' => [0, 0, 255, 0], 
      'vibrationPattern' => [500, 250, 500], 

     ]); 

     Log::info('SET THE MESSAGE'); 
    } 

    public function send() { 
     Log::info('CALLING THE SEND METHOD'); 
     if($this->android_count) { 
      PushNotification::app(env('ANDROID_PUSH_NAME')) 
       ->to($this->android_devices) 
       ->send($this->message); 
     } 

     if($this->ios_count){ 
      PushNotification::app(env('IOS_PUSH_NAME')) 
       ->to($this->ios_devices) 
       ->send($this->message); 
     } 
    } 
} 

A oto klasa Push, w której rozszerzają się wszystkie moje różne klasy wypychania.

<?php namespace App\Helpers\Push; 

abstract class Push { 
    protected $ios_devices; 
    protected $android_count; 
    protected $ios_count; 
    protected $android_devices; 
    protected $message; 
} 

Och, a tutaj także ślad stosu.

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'Erroneous data ...', '/home/forge/def...', 74, Array) 
#1 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(74): unserialize('O:28:"App\\Jobs\\...') 
#2 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(212): Illuminate\Queue\CallQueuedHandler->failed(Array) 
#3 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(261): Illuminate\Queue\Jobs\Job->failed() 
#4 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\Queue\Worker->logFailedJob('database', Object(Illuminate\Queue\Jobs\DatabaseJob)) 
#5 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(159): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), '5', 0) 
#6 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(111): Illuminate\Queue\Worker->pop(NULL, 'keen,push_notif...', 0, 3, '5') 
#7 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(87): Illuminate\Queue\Worker->runNextJobForDaemon(NULL, 'keen,push_notif...', 0, 3, '5') 
#8 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(103): Illuminate\Queue\Worker->daemon(NULL, 'keen,push_notif...', 0, 128, 3, '5') 
#9 {path_to_project}/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(71): Illuminate\Queue\Console\WorkCommand->runWorker(NULL, 'keen,push_notif...', 0, 128, true) 
#10 [internal function]: Illuminate\Queue\Console\WorkCommand->fire() 
#11 {path_to_project}/vendor/laravel/framework/src/Illuminate/Container/Container.php(507): call_user_func_array(Array, Array) 
#12 {path_to_project}/vendor/laravel/framework/src/Illuminate/Console/Command.php(150): Illuminate\Container\Container->call(Array) 
#13 {path_to_project}/vendor/symfony/console/Command/Command.php(256): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#14 {path_to_project}/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#15 {path_to_project}/vendor/symfony/console/Application.php(837): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#16 {path_to_project}/vendor/symfony/console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#17 {path_to_project}/vendor/symfony/console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#18 {path_to_project}/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(107): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#19 {path_to_project}/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) 
#20 {main} 
+0

Czy demonstrujesz proces? Jeśli używasz czegoś takiego jak Upstart lub Supervisord, czy próbowałeś zresetować demona? Wiem, że jeśli zmienisz skrypt po uruchomieniu polecenia demona, musisz go zresetować, w przeciwnym razie nie wykryje zmian. – maiorano84

+0

@ maiorano84 zobacz moją edycję. – Panda4Man

Odpowiedz

1

Okazało się, że był to problem z wersją PHP. Mój serwer działał 5.6, a kiedy zrobiłem kolejną kroplę na PHP 7.0 i sklonowałem serwer, wszystko zaczęło działać. Zostawiłem oryginalny serwer i mogłem działać jako procesor kolejki dla powiadomień push przy użyciu beanstalkd i działało jak mistrz.