Giterated stack is the unified protocol stack implementation for Giterated. The architecture of the Giterated Stack allows for easy re-use of the same stack handling code across the entire Giterated ecosystem, from daemon to client. This is aided by the aggressive type erasure when using Giterated’s Unified Stack as well as reflection to enable dynamic creation at runtime of an efficient handler stack for Giterated’s protocol.
Giterated Stack defines the type GiteratedStack
, which contains all the state necessary to handle Giterated Operations into their result. In order to do this, there is a registration process for object types, setting types, value types, operation handlers, and other metadata.
A GiteratedStack
is created by merging any number of SubstackBuilder
s into the GiteratedStack
. The creation process is completed once the GiteratedStack
is placed within an Arc
, leaving it read-only. GiteratedStack
is designed to be completely immutable at operation handling time. This means you can access it from any number of threads without concern for lock contention or other similar cases.
GiteratedStack
uses traits to embed reflection into the binary. GiteratedStack
generates this reflection metadata at runtime from traits which are inherent on the types it is reflecting.
This means that if, for example, T: ValueMeta
: T
also has an implementation of T: IntoValueMeta
.
Giterated’s Unifed Stack uses the IntoValueMeta
implementation (generated by the compiler) to populate function pointers for reflection. We avoid an extra allocation over boxed Fn*
traits.
Reflection is used in Giterated to allow for deserializing objects and operations into their concrete type as soon as possible.
Reflection is also used for values and settings, to allow for serializing and deserializing, as well as keeping the data in its concrete type.
Keeping data in Box<dyn Any>
has performance and ergonomic benefits over a ser/de intermediate style instead.
For specifics on what is reflected, how it is reflected, and how the reflection is used, please refer to the implementation of GiteratedStack
.
Giterated’s Unified Stack aims to leave compute parallelism to the caller. It contains no internal notion of runtime state, thread pools, etc.
If the caller seeks compute parallelism, they can provide that by calling Giterated’s Unified Stack from as many threads as they wish.
The design of the Giterated Unified Stack is intended to create a data structure that represents the entire stack’s state, and then operations are completed using that context. Giterated’s Unified Stack maintains no concept of tasks, threads, or thread pools; rather, Giterated’s Unified Stack exists only as the entire state needed to process an operation into a response.
giterated-stack
to be #![no_std]
with alloc
. This is to better facilitate integration through WASM support, support for more targets, and libraries that are more slim.