sillsdev / sillsdev/harmony

Add API for changes to dispatch sub changes

Open
#48 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
14
Forks
4
Avg merge
3d 21h
Merged PRs (30d)
3

Description

What

We want changes to be able to dispatch other changes. For example deletes:

public class DeleteEntryChange(Guid entityId) : EditChange<Entry>(entityId), IPolyType
{
    public static string TypeName => "delete:Entry";

    public override async ValueTask ApplyChange(Entry entry, IChangeContext context)
    {
        entry.DeletedAt = context.Commit.DateTime;
        await foreach (var obj in context.GetObjectsReferencing(EntityId, includeDeleted: false))
        {
            context.DispatchChange(new RemoveReferenceChange(obj));
        }
    }
}

or when we want to update objects which contain a copy of data

public class UpdateHeadwordChange(Guid entityId, string headword) : EditChange<Entry>(entityId), IPolyType
{
    public static string TypeName => "update:Entry:Headword";

    public override async ValueTask ApplyChange(Entry entry, IChangeContext context)
    {
        entry.Headword = headword;
        await foreach(var complexForm in context.GetObjectsReferencing(entry.Id).OfType<ComplexForm>())
        {
            context.DispatchChange(new UpdateComplexFormChange(complexForm.Id, headword));
        }
    }
}

this would also be used for data migrations, maybe previously a field was owned by an object, but you want to move that field to a different object, however you have old changes which reference the old object, you can now dispatch a change to the correct object.

Why
  • simplify delete handling code. Much of our current delete code could be moved into 2 dedicated types, one for a delete and one for removing a reference.
  • allow updating derived data, eg writing system exemplars, or complex forms.
  • data migrations, right now if you want to move a field from one object to another there's no way to write a change which allows that because a change can only modify the object it references in it's EntityId.
How

Add a new API to IChangeContext:
https://github.com/sillsdev/harmony/blob/5a660d125c4f1adc99c3384f275259b3d607d9a1/src/SIL.Harmony.Core/IChangeContext.cs#L3-L18

void DispatchChanges(params Span<IChange> changes);

this would require a lot of changes to SnapshotWorker, after a change was applied we need to gather the changes it dispatched and apply them. Much of the code in MarkDeleted will prove a useful model I suspect, however MarkDeleted itself should go away entirely as it will be handled via changes now instead.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with IChangeContext.cs to understand the proposed dispatch API, then read SnapshotWorker.cs and the existing MarkDeleted handling. Implement the dispatch flow so changes emitted during application are gathered and applied, and verify that deletion handling can move to changes as described and MarkDeleted is no longer needed.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
distributed-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.