Skip to content

Feat: temporal worker#166

Open
crazy-weasel wants to merge 15 commits intoBaldinof:3.xfrom
crazy-weasel:feat/implement-temporal
Open

Feat: temporal worker#166
crazy-weasel wants to merge 15 commits intoBaldinof:3.xfrom
crazy-weasel:feat/implement-temporal

Conversation

@crazy-weasel
Copy link
Copy Markdown
Contributor

This is based on #147

Changes made:

  • rebased to current version
  • support for ScheduleClient
  • WorkerStarted/Ended events added
  • interceptors for temporal workers:
    • DoctrineORMInterceptor
    • RebootKernelInterceptor
  • OnExceptionRebootStrategy listens to WorkerException for triggering a kernel-reboot
  • Activity-factory retrieves activities always from the current container

Some of my thoughts can be read in the original PR, starting here: #147 (comment)

Things that still need to be changed (but I'd like some feedback on):

  • The configured DataConverers are registered as services automatically (here). Sounds convinient, but I guess for the bundle it would be better to explicitly register the DataConverters coming from the temporal-sdk and just using them like in the InterceptorCompilerPass (with a check if the service is registered at all). Bundle-users should register their own services, unless a attribute or interface for autoconfiguring exists? (like for the activities)

I'd like to use the bundle and this feature in an upcoming project, so I'm very motivated to bring it up to your standards and your feedback is highly appreciated.

@rela589n
Copy link
Copy Markdown

@Baldinof , I'd like to review this

@Baldinof
Copy link
Copy Markdown
Owner

Thanks! Please, go ahead

@vlydev
Copy link
Copy Markdown

vlydev commented May 28, 2025

Hi. Any news? I want to use temporal with this bundle

Comment thread composer.json Outdated
Comment thread config/services.php Outdated
Comment thread src/BaldinofRoadRunnerBundle.php Outdated
Comment thread src/DependencyInjection/BaldinofRoadRunnerExtension.php Outdated
Comment thread src/DependencyInjection/BaldinofRoadRunnerExtension.php Outdated
Comment on lines +116 to +122
->defaultValue([
NullConverter::class,
BinaryConverter::class,
ProtoJsonConverter::class,
JsonConverter::class,
])->scalarPrototype()->end()
->end()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this approach of defining data_converters as array.

Consider if somebody would like to develop their own library, and would like to define one more data converted.

Would they be able to do it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it. now it uses tagged services ('temporal.data_converter') - apps using that bundle could just tag their own implementations. the default converters I in the extension - apps could deactivate/remove those?

Comment on lines 20 to 22
use DoctrineORMTraits;

public function __construct(ManagerRegistry $managerRegistry, ContainerInterface $container, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Composition would be better than "traiting"

namespace Baldinof\RoadRunnerBundle\Temporal\Attributes;

#[\Attribute(\Attribute::TARGET_CLASS)]
class AssignToWorker
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not making it final?

Comment on lines +53 to +54
$this->dependencies->getEventDispatcher()->dispatch(new WorkerKernelRebootedEvent());
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably service reset should be taken into account as well

     } elseif ($this->kernel->getContainer()->has('services_resetter')) {
          /** @var ResetInterface $resetter */
          $resetter = $this->kernel->getContainer()->get('services_resetter');
          $resetter->reset();
      }

Comment thread src/Temporal/WorkerOptionsFactory.php Outdated
$workerOptions = $workerOptions->withMaxConcurrentActivityExecutionSize((int) $options['max_concurrent_activity_execution_size']);
}

if (\array_key_exists('worker_activities_per_second', $options)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are all these key array_key_exists checks necessary? all of these configurations have the default value, so what's the purpose of checking it all?

$container->register("temporal.client.{$name}.factory", WorkflowClientFactory::class)
->setArguments([
'$serviceClient' => new Reference("temporal.client.{$name}.service_client"),
'$dataConverter' => new Reference('temporal.data_converter'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would also make sense to have data converter configurable per client

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I abstained from changing that for now - if it's really useful, we could add it later. for now, I finally wanted to integrate all your remarks. :) thanks again for your review :)

@rela589n
Copy link
Copy Markdown

@crazy-weasel , it seems that composer ci reports some CI errors

@crazy-weasel
Copy link
Copy Markdown
Contributor Author

Hi @rela589n thanks for the review :) I can't give you an explanation on all choices, as I just expanded on someones code, but I try to if an explanation is necessary and/or incorporate your changes / make the code better.

@crazy-weasel
Copy link
Copy Markdown
Contributor Author

Hi, I just want to let you all know, that I did not forget about the review. Unfortunately, I got sick and recovery took some time.. I'll get to it soon, after I finish some work related backlog :) Thanks for your patience!

@Baldinof
Copy link
Copy Markdown
Owner

Hi, I just want to let you all know, that I did not forget about the review. Unfortunately, I got sick and recovery took some time.. I'll get to it soon, after I finish some work related backlog :) Thanks for your patience!

It's alright, take care!

I did not had much time for this repo lately too :(

@vansante
Copy link
Copy Markdown

I have been following this PR with some interest as I am working on a Temporal project, and have thus been evaluating this bundle with this feature.

I ran however into a bug in the latest commit of this PR, whenever I am trying to execute an Activity, I run into a ReflectionException:

./var/log/dev.log:[2025-07-11T13:24:34.033166+00:00] app.ERROR: An error occured: Given object is not an instance of the class this method was declared in {"throwable":"[object] (BadMethodCallException(code: 0): Given object is not an instance of the class this method was declared in at /app/vendor/temporal/sdk/src/Internal/Declaration/Dispatcher/Dispatcher.php:101)
[previous exception] [object] (ReflectionException(code: 0): Given object is not an instance of the class this method was declared in at /app/vendor/temporal/sdk/src/Internal/Declaration/Dispatcher/Dispatcher.php:99)"} []

This error went away when I went to a commit earlier (23c05a054d6fb868df5a9c613a302bed5c6b06c7). The workflow worked fine under that revision.

It seems introducing the activity factories introduced a bug which is tripping up the Dispatcher reflection logic.

@versh23
Copy link
Copy Markdown

versh23 commented Dec 3, 2025

hi! any updates?

@xepozz
Copy link
Copy Markdown
Contributor

xepozz commented Feb 17, 2026

Any updates?

@rela589n
Copy link
Copy Markdown

Guys, you are the driving force of updates 🙂

praswicaksono and others added 10 commits March 27, 2026 17:03
renames ClientFactory to WorkflowClientFactory
adds ScheduleClientFactory
fixes typo
removes redundant code
- adding two default interceptors for using the configured reboot-strategie and for Doctrine ORM
- registering activities with a factory that fetches the activities from the DI container. that way, new activity-instances are created when the kernel was rebooted.
- dispatching events similar to the other workers
- OnExceptionRebootStrategy now listens to the WorkerExceptionEvent
add tests
change dataconverters from configured as an array, to tagged services
@crazy-weasel crazy-weasel force-pushed the feat/implement-temporal branch from a71542a to 5f17af3 Compare March 28, 2026 20:32
@crazy-weasel
Copy link
Copy Markdown
Contributor Author

hi everyone :)

sorry for the long wait, but I finally took the time to implement (almost) all of @rela589n suggestions.

the data converters are still only configured once for all client. I guess that's good enough for now?

I guess tomorrow I'll have an additional look into the debug-commands, and also to adding a data-collector for the symfony profiler. at least for displaying information about started workflows within a request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants