0

Having the most strange error I've ever encountered in my coding journey.

I am using: laravel ratchet websocket Laravel Cache with file driver

I am trying to cache ratchet websocket response messages from within its closure function using laravel cache from an artisan command's class.

When I use var_dump on the websocket response, I get all the messages printed out on my terminal. But when I try to save in cache, it return true but the cache is empty. Not get stored, no error message is displayed.

This is my code:

use Illuminate\Support\Facades\Cache as Cache;


class Ticker extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'daemon:t';

    /**
     * The console command description.
     *
     * @var string
     */
    
    protected $description = 'Listens to websockets t';
    /**
     * Create a new command instance.
     *
     * @return void
     */
     protected $cah;
    public function __construct(Cache $Cache)
    {
        $this->cah = new $Cache();
        parent::__construct();
        

    }
    
  


    public function mini(callable $callback)
    {

        // phpunit can't cover async function
        \Ratchet\Client\connect('wss://stream......')->then(function ($ws) use ($callback) {
            $ws->on('message', function ($data) use ($ws, $callback) {
                
                $json = json_decode($data, true);

                return call_user_func($callback, $this->cah, $json);
            });
            $ws->on('close', function ($code = null, $reason = null) {
                // WPCS: XSS OK.
                echo "....: WebSocket Connection closed! ({$code} - {$reason})" . PHP_EOL;
            });
        }, function ($e) {
            // WPCS: XSS OK.
            echo "....: Could not connect: {$e->getMessage()}" . PHP_EOL;
        });
        
    }
       
       
    // save 
    
    public function saveT($t){
      //$this->alert($t);
      
      try{
         foreach ($t as $obj) {
              $this->cah::put($obj['s'], $obj, now()->addSeconds(5));
          }
      // used in testing
      //print_r($t);
 
      } catch (\Exception $exception) {
          $this->alert($exception->getMessage());
      }
    }
    
    
    /**
     * Execute the console command.
     *
     * @return mixed
     * @throws \Exception
     */
            
    public function handle()
    {
        
        $this->mini(function ($api,$json){
          
           // saving directly though the $api object 
           $api::put(['s' => $json], now()->addSeconds(10));
         
            // when savingnthrough saveT function 
          // $this->saveT($json);
          
         
         try{
           // call_user_func_array(array($this->cah::class,'put'),array('test','tested',now()->addSeconds(5)));
        } catch (\Exception $exception) {
             $this->alert($exception->getMessage());
        }
       },);
    }
}

  • `$cache` and `$Cache` are two different variables (variables are case sensitive). – M. Eriksson Sep 24 '21 at 22:27
  • In your second example (where you use the full namespace), you still have `use (&$Cache)`, which isn't needed there (and will fail if you haven't defined `$Cache`). While developing, make sure that you're [displaying all errors and warnings](https://stackoverflow.com/questions/1053424/how-do-i-get-php-errors-to-display), because I don't see how all attempts can fail without errors/warnings (specially when you should get "undefined variable"-notice/warning) – M. Eriksson Sep 24 '21 at 22:34
  • sorry about that, the mistake have been here while formatting my question. Within the code it is referenced properly (first letter Cap ) – Babila Vena Sep 24 '21 at 22:36
  • Please copy/paste your actual code instead of rewriting it here. When debugging code, it's crucial that we see your exact code. Rewrites can introduce other issues (like your variable casing) or even unintentionally fix real issues. – M. Eriksson Sep 24 '21 at 22:37
  • I've added the final piece of code I want working at the end. I just want the cache focade executed within the closure. – Babila Vena Sep 24 '21 at 22:51
  • So what is the problem? We need more than just "not working" or "failing without errors". Is the function even being executed? What debugging have you done? Have you turned on error reporting and display errors? Have you checked the web servers error log? – M. Eriksson Sep 24 '21 at 23:06
  • I am using laravel telescope, my .env log level is debug. Once I use the above code, it doesn't show error. Neither does it save cache items. if I wrongly spell anything or change the namespace to a wrong one. It will display error message. If I try to cache an item out of the scope of the closure, it works perfectly well. – Babila Vena Sep 24 '21 at 23:15
  • https://www.php.net/manual/en/language.types.callable.php – Sammitch Sep 24 '21 at 23:51
  • I've added the complete code and more details. Cache is not saving, cache put function returns true which probably means its been saved but that's not the case. There is no permission issues at server level as cache works well when used out of the closure. – Babila Vena Sep 27 '21 at 22:41

1 Answers1

0

The example code you've posted is a tangle of conflicting conventions, names, and references. Once you sort out what it is that you actually need, here are the correct forms for actually constructing and and invoking the callables.

namespace foo {
    class Cache {
        public static function put_static($a, $b, $c='optional?') {
            echo "put_static: $a $b $c\n";
        }
        
        public function put_instance($a, $b, $c='optional?') {
            echo "put_instance: $a $b $c\n";
        }
    }
}

namespace {
    use foo\Cache as Cache;
    $c = new Cache();
    
    $callback_static          = [Cache::class, 'put_static'];
    $callback_instance        = [$c,           'put_instance'];
    $callback_instance_static = [$c::class,    'put_static'];
    
    $vars_a = ['a', 'b'];
    $vars_b = ['a', 'b', 'c'];
    
    call_user_func_array($callback_static, $vars_a);
    call_user_func_array($callback_static, $vars_b);
    
    call_user_func_array($callback_instance, $vars_a);
    call_user_func_array($callback_instance, $vars_b);
    
    call_user_func_array($callback_instance_static, $vars_a);
    call_user_func_array($callback_instance_static, $vars_b);
}

Output:

put_static: a b optional?
put_static: a b c
put_instance: a b optional?
put_instance: a b c
put_static: a b optional?
put_static: a b c

You can also save some keystrokes with the splat operator ... to unpack the array as arguments, so call_user_func_array($func, $args) becomes $func(...$args)

Ref:

Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • Thanks so much for your constructive reply.. at this level I have no problem at all. The code stopped working when I tried calling call_user_func_array($callback_instance_static, $vars_b); within a closure function. Due to scope – Babila Vena Sep 25 '21 at 22:37
  • Please look into my complete code uploaded. Using var_dump, the returned result of the put method ofnthe cache class shows true. normally it should've been saved but no cache items are saved and no error messages. I believe with the complete code you can spot the error or recreate at your end. Thanks – Babila Vena Sep 27 '21 at 22:40