-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/job request deiscriminator #1693
Conversation
…ters bson serializers
…viders and bson serializers
I'm a bit stuck here on how to actually do the Bson serializer part... @einari |
Docker Image for this PR: docker run ghcr.io/cratis/chronicle:10.9.9-pr1693.4de85fa |
I've done something that might be useful for this. In fact, this is something that was accidentally removed from ApplicationModel and should be put back. Fundamentals has the concept of derived types, which also stores a discriminator. This is done using a Guid, but our case would be the String representation. It leverages the Convention system in the MongoDB driver: https://github.com/einari/MongoDB/blob/main/Source/DerivedTypeDiscriminatorConvention.cs This is the serializer: https://github.com/einari/MongoDB/blob/main/Source/DerivedTypeSerializer.cs This is the provider that provides the serializer: https://github.com/einari/MongoDB/blob/main/Source/DerivedTypeSerializerProvider.cs |
The issue here is that we need to know the JobType when serializng the IJobRequest so we need a serializer for JobState as well? That's the part i don't understand, the problem is serializing the IJobRequest, we want to know it's concrete clr type consistently and we only know that through the JobType. As far as I understand that was the idea |
The discriminator approach would do just that. The only downside is that the JobType would then be part of the Request BSON object. An option here would be to stick the JobType on the IJobRequest interface. Then the discriminator convention approach would be fine and we wouldn't need a custom serializer for JobState. I think this option is fine. If we want to expose JobType on the JobState level as well, we would need to keep the two in sync. But I don't think we would need it on the JobState level, as the Request is not optional (if I remember correctly) |
I understand what you're saying, however I think it's strange for the JobState to not have the JobType and the IRequest to have it instead. It's also a bit weird from a instantiation point of view for the IRequest when we make it we have to supply the JobType in the constructor, or use the IJobTypes in the IRequest implementations instead or something like that. It's just a bit strange |
Would be nice if we could getting a reference to the parent bson document when we serialized the IJobRequest 😓 |
@einari BsonReaderBookmark did the trick for me :) I have one question though in relation to removing Request from JobStepState, /// <summary>
/// Represents the <see cref="JsonConverter{T}"/> that can convert <see cref="JobStepState"/>.
/// </summary>
public class JobStepStateJsonConverter : TypeWithObjectPropertiesJsonConverter<JobStepState>
{
/// <inheritdoc/>
protected override IEnumerable<string> ObjectProperties => [nameof(JobStepState.Request)];
} |
Great. That Json converter can probably be deleted. I believe it was there for the frontend APIs. But the APIs are now using the gRPC contracts and if we want to expose the request information in the APIs, we'll figure something out. Like we do :) |
Do we have to do kind of the same thing for the json serializer? |
Ahh.. Damn.. Ideally we should get rid of Json serialization of our internal types and create Orleans Codecs instead. But I have a sneaky suspicion that is a bigger fish to fry right now. |
This is also very annoying, this is just the same problem as with the MongoDB serializer, where we cannot create a converter just for IJobRequest because we don't have JobType and no way to reference parent object. And it's even more anoying with JsonConverter for JobType because there I don't have access to the service provider so I cannot use IJobTypes either.... This just keeps spiraling 😭 |
Well, depends. E.g.: In globals we use it: Furthermore, we could have the JsonConverter have 2 constructors, one that takes the IJobTypes as a dependency (making it testable with mocks) and a default one that forwards to this passing the public class JobRequestConverter
{
public JobRequestConverter() : this(JobTypes.Instance);
public JobRequestConverter(IJobTypes jobTypes)
{
}
} |
If this is the way we have to go then I guess we don't have much better alternatives 😄 |
There are always alternatives :) https://github.com/Cratis/ApplicationModel/blob/main/Source/DotNET/Applications/Internals.cs Its basically exposing the ServiceProvider internally. This could then be set like we do in AppModel: Either way, its not optimal and perfect. They're all trade-offs. Pragmatically speaking, its fine. |
But for this use case, its probably better with my previous suggestion, as the ServiceProvider is probably not ready at the time of setting up the serializer options. |
fixes #1686 |
Added
Fixed
Removed