Gothic: Difference between revisions
Adamcolton (talk | contribs) |
Adamcolton (talk | contribs) No edit summary |
||
| Line 89: | Line 89: | ||
* Wiki | * Wiki | ||
* Work logs | * Work logs | ||
== Terms and Ideas == | |||
* Module: A unit of code that adds functionality to a project | |||
* Package: A collection of modules and packages | |||
* Handler: A unique event handler. Modules and packages may require handlers to be enabled. | |||
Revision as of 15:25, 1 October 2015
The successor to Ghost and Lapiz.
Gothic runs in Go on a dedicated server. It is not meant to run behind Apache or share the machine with other services. But it can make efficient use of very small machines and scale out to utilize additional nodes efficiently.
Components
- Blueprints: schemas, data designs
- Mason: server level compiler
- Carpenters: UI (JS,CSS,HTML) compiler
- Arch: UI runtime
- Vault: Persistance
- Portal: API/transport
- Spire: UI
- Lancet: Core(server) framework
Blueprints
Gothic is built around blueprints. A blueprint is like a model or schema. It defines a set of data and it's relationships.
Blueprints also define special modifies for:
- UI
- Storage
- non-persistant fields
- manually defined indexes
- auto-indexing
- API
- Validation
All instances are entities. They have an id field, a guid.
Arch
This is the hard bit. How to take the blueprints and translate them to something powerful, mostly automated, but still flexible.
I think it will use 2 Web Workers + the main window by default. One worker will handle any processing, the other will handle networking. If the models are all encoded as ArrayBuffers, they can be passed around easily. I can also translate their code to Asm.js. But this means they cannot interact in Asm.js.
Unlike Lapiz, I will not do strict privacy, instead relying on the compiler to enforce this.
Just figured out function tables in Asm.Js, that puts a lot back on the table.
Vault
Vault is the persistence layer, an object store and caching mechanism.
Store
- obj.EntityId() []byte
- obj.Serialize() string
- gothic.NewContainer(zero Obj, directory) Container
Serializing is a bit tricky. Can't use Gob because it needs to not follow Entity references, but instead replace them with Entity Ids. Further, I'd like a default serializer to "just work", but I'd also like to allow users to either write their own or have a chance to store hidden state.
Also, it would be best if default serialization happened in such a way that a subset of fields could be loaded without hydrating the whole object.
I think the best approach is to have Encoding. An Encoding can Encode or Decode. For a given Encoder, no reflection is used. But an Encoder can be created via a function that uses reflection.
Cache
- WeakRef map
- Finalize
- PostGC
The WeakRef map tracks active Entities so that we don't have multiple clones instantiated. I can also do a mutex lock here so that two routines don't hydrate at the same time. Finalize will transfer an object from Active to Cached. PostGC we will check memory usage and if it's too high, we'll (proportionally) drop the oldest part of the cache.
Index
- map[string]LessThan(obj, val) bool
This allows us to do comparisons. To compare two objects, we extract the field from one and pass it in as a value.
Query
- Filter(obj) bool
Not much explanation needed. However, with this setup, devs need to be aware of their indexes and first filter using indexes then filter using explicit filters. I need to find a way to make this easier. The best bet would be a standard Filter interface that can be reduced to less-than operations.
Crazy Idea
Go has function pointers and unsafe. It may be possible to generate Go code, spin it up in separate process, pass a pointer through a pipe, and copy the function.
Spire
This manages CSS and HTML templates. I want something very much in line with LapizUI. We have Templates and Meta-Templates. They are logic free and instead expose hooks that need to be handled in application logic. When an entity is merged with a template it can be rendered to a target. A Meta-Template can be merged with a blueprint to produce a template.
Themeing is broken up a bit more here than in most frameworks. One portion of themeing handles page blocks.
Templates and Meta-templates have types (edit, create, full, short, list) and are arranged in packages (though a single template can be a package). It will be possible to request that a specific template or meta-template be used in some instance, but the more common procedure will be to choose the type and have the theme engine choose the best fit. This will be done with a precedent order. So a theme will ship with some default meta-templates. Modules can define their own templates (for their types).
Credential Model
There are two types of credentials. One is token access. This is where a user or process gains access by having access to a token object. The other is secret knowledge. This is like a password.
Using a CMS as an example; a user could sign in with a username and password. Now they have this credential object to access and edit content. But rather than giving each user access to individual objects, we create roles, which are access tokens and user object is only used to retrieve a role token.
Portal
This is the API layer. It primarily works over websockets. A user or process provides a request. The system uses their credentials to see if they have access to the results of the request. The objects that match, that the requester can access, are returned.
Though Experiments
- Basic relay chat server
- Wiki
- Work logs
Terms and Ideas
- Module: A unit of code that adds functionality to a project
- Package: A collection of modules and packages
- Handler: A unique event handler. Modules and packages may require handlers to be enabled.