brefphp / laravel-bridge

Package to use Laravel on AWS Lambda with Bref
https://bref.sh/docs/frameworks/laravel.html
MIT License
314 stars 63 forks source link

No Access To Lambda Context #78

Open matthewsuan opened 1 year ago

matthewsuan commented 1 year ago

serverless.yml

...
  worker:
    handler: worker.php
    timeout: 900
    layers:
      - ${bref:layer.php-81}
    events:
      - sqs:
          arn: !GetAtt GPT3Queue.Arn
          batchSize: 3
...

Worker.php

<?php declare(strict_types=1);

use Bref\LaravelBridge\Queue\LaravelSqsHandler;
use Illuminate\Foundation\Application;

require __DIR__ . '/vendor/autoload.php';
/** @var Application $app */
$app = require __DIR__ . '/bootstrap/app.php';

/**
 * For Lumen, use:
 * $app->make(Laravel\Lumen\Console\Kernel::class);
 * $app->boot();
 */
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();

return $app->makeWith(LaravelSqsHandler::class, [
    'connection' => 'sqs', // this is the Laravel Queue connection
    'queue' => getenv('SQS_QUEUE'),
]);

Inside the queues, it seems I don't have access to the lambda context. $_SERVER['LAMBDA_INVOCATION_CONTEXT'] is missing. Am I doing something wrong?

mnapoli commented 1 year ago

Hi, $_SERVER['LAMBDA_INVOCATION_CONTEXT'] is only available when running with the "FPM" layer (in HTTP context). It won't work for queues.

One reason is that the same PHP process can be kept alive to handle multiple SQS jobs (for example), so we cannot set the values in an environment variable.

One way would be for you to write a custom SqsHandler class, but then you loose all the features of Laravel Queues :/

Could you explain what information you want to access in the invocation context?

Also I wonder if it's possible to store the context somewhere in the Laravel job 🤔

matthewsuan commented 1 year ago

@mnapoli I wanted to access the deadlineMs value so I can pre-emptively do something before a lambda timeout occurs.

Do you think we can add support to this?

mnapoli commented 1 year ago

We could, but we need to figure out how and where's the best place to put this information. Any idea?

matthewsuan commented 1 year ago

Inside LaravelSqsHandler.handleSqs we have access to Context object but then it was never used. I think we can set $_SERVER['LAMBDA_INVOCATION_CONTEXT'] from there same way we did with the FpmHandler?

Or we could also push the context object down further to SqsJob as object props.

I am very willing to open up a PR for this but just wanted to be sure this is in line with the general direction of Bref.

mnapoli commented 1 year ago

$_SERVER won't work because of the reasons listed here: https://github.com/brefphp/laravel-bridge/issues/78#issuecomment-1313368497

Adding that in SqsJob could be a better option indeed, but is there a good place for it that doesn't pollute the job's data?