Skip to content

Conversation

@CunningFatalist
Copy link
Collaborator

Ticket

@paroe

I will NOT merge this PR, it's just here to make your live easier.

This should fix all deprecations and composer issues.

@CunningFatalist CunningFatalist requested a review from paroe April 8, 2024 10:36
@CunningFatalist CunningFatalist self-assigned this Apr 8, 2024
@CunningFatalist
Copy link
Collaborator Author

@paroe Found some more issues with PhpStorm. They are fixed now and this is ready for review.

Copy link
Owner

@paroe paroe left a comment

Choose a reason for hiding this comment

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

I found some issues, mainly in the serialization of the StackTrace / Exception. I'll try to fix this

use Doctrine\DBAL\Types\JsonType;

class SafeObjectType extends ObjectType
class SafeObjectType extends JsonType
Copy link
Owner

Choose a reason for hiding this comment

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

This causes some trouble. We currently have data in the database and that is stored (in Application:87) by serializing a FlattenException. That means that jobs without an error always have N; as the value, and jobs with an error a mega long hex value that looks something like 0x4F3A35373A2253796D666F6E795C436F6D706F6....
This of course can't be handled by the JsonType, so the worker do not start if there are existing jobs.

So, we are dealing with two problems here:

  1. the value in the database has to become a JSON for existing jobs
  2. the value in the database has to become a JSON for new jobs

And a third one:
3. This has to be done ideally in a backwards compatible way so that we can migrate back if we need to and ideally have the old and the new workers running at the same time (probably not possible)

The first problem can probably be solved by a migration. But that is not backards-compatible then. So, maybe we have to consider to add a new column.

I tried json_encode for the FlattenException, but unfortunately that just returns an empty JSON object. I was not able yet to find another way to get a proper JSON from nested exceptions. I think that we maybe have to consider just saving the stacktrace as string, but then we lose some valuable information, like the exception message.

I'll try to create a JsonSerializable FlattenException; that should solve that problem. And I am thinking of either rewriting the JobSafeObject to handle both - the old and the new - style in the database. But then we still have to perform a double deployment. I think it might be easier to write a migration that rewrites the stuff in the database, but I fear that this is can't be reversed. So the better solution is probably to introduce a new column and just set the existing one always to N; until we can finally remove / rename it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As far as I remember, that's a change that I had to make. I didn't stumble across those implications during my testing. So my current status is that you don't need help with this (anymore)?

Copy link
Owner

Choose a reason for hiding this comment

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

yes exactly; I have pushed the updated code with all my fixes that were required (see also my other comments)

Copy link
Owner

Choose a reason for hiding this comment

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

I didn't stumble across those implications during my testing.

Probably because you didn't have old jobs in your database that were already executed. The stacktrace is only written when a job has been started and not when the job is still pending. So, this is an edge case that our tests can not really cover and I also only discovered this when I tried to activate the workers on Staging

* @method Job[] findAll()
* @method Job[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class JobRepository extends ServiceEntityRepository
Copy link
Owner

Choose a reason for hiding this comment

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

Did you have to create this repository? In Indiana I am getting an error about a missing service when I try to open an job in the admin view. I'll try to remove this repository, maybe that also works (as the JobManager does all the repository stuff already)
image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was automatically created and I thought it wouldn't hurt. But then again, it does. Do you want me to remove it?

Copy link
Owner

Choose a reason for hiding this comment

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

I am not sure, why exactly this is an issue. I assume that we might have to rewrite the bundle's DI to fix this if we wanted to use the explicit repository. But as it is not needed I just removed it.

public function __construct(ManagerRegistry $managerRegistry, JobManager $jobManager, EventDispatcherInterface $dispatcher, array $queueOptionsDefault, array $queueOptions)
{
parent::__construct();
parent::__construct('jms-job-queue:run');
Copy link
Owner

Choose a reason for hiding this comment

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

I had to move the name to the constructor because the constructor calls configure at the very end. And if you then call setName after the constructor already ran you can't extend commands anymore. This normally is not a problem, but Indiana extends the RunCommand (app:jms:run) because we have to add an additional parameter ("hostname"); and this setName made our command unavailable as the original one took precendence.
And there is also some extra logic regarding aliases in the constructor that is not executed in this case, but we don't need that

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh damn, good point.

'memoryUsage' => memory_get_peak_usage(),
'memoryUsageReal' => memory_get_peak_usage(true),
'trace' => serialize($ex ? FlattenException::create($ex) : null),
'trace' => $trace,
Copy link
Owner

Choose a reason for hiding this comment

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

In the past the data was a serialized PHP object; but now it has to be valid JSON.
I also tried to add a new column for this (so that old runners that are still running can keep that column and new runners can use the new column); but this caused a lot of trouble of invalid database schemas (because of the unknown columns) and also caused trouble because of the SafeObject type; so in the end I decided that we have to make sure that either old or new runners are running exclusively and that we have to migrate the database manually if we want to switch between the runners. That is quite ugly, but the only thing that did not require implementing a custom database adapter to circumvent the validation errors

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't even think it's that ugly; it's an okay solution. Nice fix

@paroe
Copy link
Owner

paroe commented May 13, 2024

@CunningFatalist I committed my changes to fix the issues that I found, see this commit. I guess I maybe should have created a new PR to make the review easier, but in the end only very few things have changed. I have just added some types to the Job entity to get rid of some of the deprecation messages


try {
$trace = json_encode($ex ? FlattenException::create($ex)->toArray() : null, JSON_THROW_ON_ERROR);
} catch (\JsonException) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You could use this, but it's not really important.

@CunningFatalist
Copy link
Collaborator Author

@paroe

Thanks for fixing this. The commit you linked looks good.

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.

3 participants