Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
woksin committed Feb 4, 2025
1 parent c3133c6 commit f198c5a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 5 deletions.
7 changes: 7 additions & 0 deletions Source/Kernel/Concepts/Jobs/IJobTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,11 @@ enum GetForError
/// <param name="type">The <see cref="JobType"/>.</param>
/// <returns><see cref="Result{T0, T1}"/> <see cref="Type"/> or <see cref="GetRequestClrTypeForError"/>.</returns>
Result<Type, GetRequestClrTypeForError> GetRequestClrTypeFor(JobType type);

/// <summary>
/// Gets the job request <see cref="Type"/> associated with the <see cref="JobType"/>.
/// </summary>
/// <param name="jobRequestClrType">The job request clr type.</param>
/// <returns><see cref="Result{T0, T1}"/> <see cref="Type"/> or <see cref="GetRequestClrTypeForError"/>.</returns>
Result<Type, GetRequestClrTypeForError> GetJobClrTypeFromRequestClrType(Type jobRequestClrType);
}
17 changes: 15 additions & 2 deletions Source/Kernel/Grains/Jobs/JobTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class JobTypes : IJobTypes
readonly Dictionary<JobType, Type> _jobTypes = [];
readonly Dictionary<Type, JobType> _jobTypePerType = [];
readonly Dictionary<JobType, Type> _jobRequestTypes = [];
readonly Dictionary<Type, Type> _jobRequestTypeToJobType = [];

/// <summary>
/// Initializes an instance of the <see cref="JobTypes"/> class.
Expand Down Expand Up @@ -56,6 +57,14 @@ public class JobTypes : IJobTypes
: IJobTypes.GetRequestClrTypeForError.CouldNotFindType;
}

/// <inheritdoc/>
public Result<Type, IJobTypes.GetRequestClrTypeForError> GetJobClrTypeFromRequestClrType(Type jobRequestClrType)
{
return _jobRequestTypeToJobType.TryGetValue(jobRequestClrType, out var jobClrType)
? jobClrType
: IJobTypes.GetRequestClrTypeForError.CouldNotFindType;
}

void InitializeMap(ITypes types)
{
PopulateJobTypes(types);
Expand All @@ -64,7 +73,9 @@ void InitializeMap(ITypes types)

void PopulateJobTypes(ITypes types)
{
foreach (var jobClrType in types.FindMultiple<IJob>().Where(type => type is { IsClass: true, IsAbstract: false } && type != typeof(NullJob)))
foreach (var jobClrType in types.FindMultiple<IJob>()
.Where(type => type is { IsClass: true, IsAbstract: false, IsInterface: false, IsGenericType: false }
&& type != typeof(NullJob) && type.Assembly.FullName != typeof(IJob).Assembly.FullName))
{
var jobTypeAttribute = jobClrType.GetCustomAttribute<JobTypeAttribute>();
var jobType = jobTypeAttribute?.JobType ?? jobClrType;
Expand Down Expand Up @@ -95,7 +106,9 @@ void PopulateJobRequestTypes()
throw new JobTypeMustHaveARequestType(jobType, jobClrType);
default:
// First generic argument of IJob<TRequest> is the type of the request
_jobRequestTypes.Add(jobType, jobInterfaces[0].GetGenericArguments()[0]);
var requestType = jobInterfaces[0].GetGenericArguments()[0];
_jobRequestTypes.Add(jobType, requestType);
_jobRequestTypeToJobType.Add(requestType, jobClrType);
break;
}
}
Expand Down
54 changes: 51 additions & 3 deletions Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (c) Cratis. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Cratis.Applications.MongoDB;
using Cratis.Chronicle.Concepts.Jobs;
using Cratis.Chronicle.Storage.Jobs;
using Cratis.Strings;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
Expand All @@ -15,21 +17,67 @@ namespace Cratis.Chronicle.Storage.MongoDB.Jobs;
/// <param name="jobTypes">The <see cref="IJobTypes"/>.</param>
public class JobStateSerializer(IJobTypes jobTypes) : SerializerBase<JobState>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JobState value)
{
var requestType = value.Request.GetType();
var requestSerializer = BsonSerializer.SerializerRegistry.GetSerializer(requestType);
}
/// <inheritdoc />
public override JobState Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var jobRequestElementName = nameof(JobState.Request).ToCamelCase();
var rawBsonDocument = context.Reader.ReadRawBsonDocument();
using var rawDocument = new RawBsonDocument(rawBsonDocument);
rawDocument.Remove(jobRequestElementName);
var bsonDocument = rawDocument.ToBsonDocument<BsonDocument>();
var jobTypeString = bsonDocument.GetValue(nameof(JobState.Type).ToCamelCase()).AsString;
var jobRequestType = jobTypes.GetRequestClrTypeFor(new(jobTypeString)).AsT0;
var jobRequestElementName = nameof(JobState.Request).ToCamelCase();
var request = (IJobRequest)BsonSerializer.Deserialize(
bsonDocument.GetElement(jobRequestElementName).ToBsonDocument(),
jobRequestType);
bsonDocument.Remove(jobRequestElementName);
// bsonDocument.Remove(jobRequestElementName);

Check warning on line 38 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 38 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 38 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

var jobState = BsonSerializer.Deserialize<JobState>(bsonDocument);
jobState.Request = request;
return jobState;
}
}
}

public class JobRequestSerializer<TJobRequest>(IJobTypes jobTypes) : SerializerBase<TJobRequest>

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Parameter 'jobTypes' is unread.

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Parameter 'jobTypes' is unread.

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

Parameter 'jobTypes' is unread.

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

Check warning on line 45 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

where TJobRequest : IJobRequest
{
/// <inheritdoc />
public override TJobRequest Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var rawBsonDocument = context.Reader.ReadRawBsonDocument();
using var rawDocument = new RawBsonDocument(rawBsonDocument);
var bsonDocument = rawDocument.ToBsonDocument<BsonDocument>();
return BsonSerializer.Deserialize<TJobRequest>(bsonDocument);
}
}

/// <summary>

Check warning on line 58 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Add 'param' element to documentation comment (https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1141)

Check warning on line 58 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Add 'param' element to documentation comment (https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1141)

Check warning on line 58 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

Add 'param' element to documentation comment (https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1141)
/// Represents a <see cref="IBsonSerializationProvider"/> for concepts.
/// </summary>
public class JobRequestSerializationProvider(IServiceProvider serviceProvider) : IBsonSerializationProvider

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / publish-nuget-packages

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / kernel

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

Check warning on line 61 in Source/Kernel/Storage.MongoDB/Jobs/JobStateSerializer.cs

View workflow job for this annotation

GitHub Actions / integration

{
/// <summary>
/// Creates an instance of a serializer of the concept of the given type param T.
/// </summary>
/// <typeparam name="T">The Concept type.</typeparam>
/// <returns><see cref="ConceptSerializer{T}"/> for the specific type.</returns>
public static JobRequestSerializer<T> CreateSerializer<T>(IServiceProvider serviceProvider)
where T : class, IJobRequest
=> ActivatorUtilities.CreateInstance<JobRequestSerializer<T>>(serviceProvider);

/// <inheritdoc/>
public IBsonSerializer GetSerializer(Type type)
{
if (type.IsAssignableTo(typeof(IJobRequest)))
{
var createSerializerMethod = GetType().GetMethod(nameof(CreateSerializer))!.MakeGenericMethod(type);
return (createSerializerMethod.Invoke(null, [serviceProvider]) as IBsonSerializer)!;
}

return null!;
}
}

0 comments on commit f198c5a

Please sign in to comment.