|
| 1 | +# How to Prune (GC) Grit? |
| 2 | + |
| 3 | +How do we prune the Grit DAG? This requires a garbage collection type system. |
| 4 | + |
| 5 | +The main idea is pretty simple: grit needs to be extended so that the "previous" fields in messages or steps can be set to "None" while maintaining a "soft-link" to the history. |
| 6 | + |
| 7 | +Here is how this could look like: |
| 8 | +``` |
| 9 | +Message = NamedTuple("Message", |
| 10 | + [('previous', MessageId | None), |
| 11 | + ('previous-pruned', MessageId | None), --only one or the other "previous.." would be allowed to be set |
| 12 | + ('headers', Headers | None), |
| 13 | + ('type', str), |
| 14 | + ('content', BlobId | TreeId | None)]) |
| 15 | +``` |
| 16 | + |
| 17 | +If `previous-pruned` is set, `previous` is not allowed to be set. Although this maintains a historical link to the obj ids that came before, they can be discarded by the garbage collector. |
| 18 | + |
| 19 | +## Messages |
| 20 | +Maintaining a link to the history is important for the message object type because it allows an actor to send a pruned message list, giving the recipient a chane to process also previous, now pruned messages before it accepts the message with the prune marker. |
| 21 | + |
| 22 | +## Lifecycle |
| 23 | +The runtime would probably send "prune" signals to each actor when it is time to prune. But actors could also decide to prune messages or step histories on their own initiative. The mechanics would be the same |
| 24 | + |
| 25 | + 1) Runtime sends "prune signal" via normal message |
| 26 | + 2) Actor sends a pruned message to all or most of its outbox |
| 27 | + 3) Actor also incorporates a prune marker in the new step |
| 28 | + 5) (later and indepenently) reviever accepts the pruned messages in its inbox, completeing the cycle for that message channel. |
| 29 | + 4) Grit can now garbage collect the messages and steps that are not needed anymore |
| 30 | + |
| 31 | +## Maintaining Some History |
| 32 | + |
| 33 | +It would be nice if an actor could retain *some* history of what happened to it. That is, if a prune request does not prune all the way to the present moment, but rather a little bit back. |
| 34 | + |
| 35 | +How much back could be configurable (or part of the prune request signal). |
| 36 | + |
| 37 | +How to do this? |
| 38 | +``` |
| 39 | +Message = NamedTuple("Message", |
| 40 | + [('previous', MessageId | None), |
| 41 | + ('prune-from', MessageId | None), --if set, prunes back from the message id specified here |
| 42 | + ('headers', Headers | None), |
| 43 | + ('type', str), |
| 44 | + ('content', BlobId | TreeId | None)]) |
| 45 | +``` |
| 46 | +In this case, `previous` would still be always set (if it is a message queue), and `prune-from` would indicate any message id in the history of previous messages where to prune from... |
| 47 | + |
| 48 | +However, it is not certain if this is the best design. It requires a lot on the part of the actor. Altenatively, the pruning happens often, which would result in many pruning markers throughout the history, *and then the runtime or Grit decides what to actually prune.* |
| 49 | + |
| 50 | +In the second design, the prune messages could also contain some sort of timestamp which allows grit to decide, but grit could maintain that timestamp too. |
| 51 | + |
| 52 | +With the most sleek design the message could just have a flag whether pruning previous messages is allowed, everything else would stay the same: |
| 53 | + |
| 54 | +``` |
| 55 | +Message = NamedTuple("Message", |
| 56 | + [('previous', MessageId | None), |
| 57 | + ('prune', bool), --if set, prunes back from the message id specified here |
| 58 | + ('headers', Headers | None), |
| 59 | + ('type', str), |
| 60 | + ('content', BlobId | TreeId | None)]) |
| 61 | +``` |
| 62 | + |
| 63 | +I'm not sure if there is a better way to indicate the prune marker... I think somehow the first design at the very top is better, because it makes the prune action much more explicit than a flag (branching mechanisms have to be introduced anyhow). |
| 64 | + |
| 65 | +Finally, it could also be that we simply have Grit track the time and prune without any markers and/or involvement of the actors. But that would make it difficult to guess whether data or history is available or not. Especially if the wit logic relies on the history (such as comparing two obejects how they changed over history). The actor would have no way to know why data is not available in Grit (although we could return a "pruned" object if it doesnt exist anymore, but then that would work like an additional null, which is bad, better make it explicit). |
0 commit comments