neos / contentrepository-development-collection Goto Github PK
View Code? Open in Web Editor NEWWork in Progress on the Event Sourced Content Repository as installable set of packages
Work in Progress on the Event Sourced Content Repository as installable set of packages
We assume objects to exists in some places where they can be null
currently¹.
To avoid nasty PHP errors we should cater for those cases and check for null or adjust the API to avoid null cases to begin with.
¹ The EA inspections plugin can help to find possible null pointers in PhpStorm
Currently, the Neos UI in https://github.com/neos/neos-ui/blob/master/packages/neos-ui-redux-store/src/CR/Nodes/selectors.js#L18 determines the parent context path by manipulating the context path string directly, which of course does not work anymore for node addresses which have no hierarchy.
We need to refactor the UI to not rely on this behavior anymore.
from @kitsunet
Neos.Neos:Sites
root node which (after transforming the demo site to events) has no dimension values. So in that dimensionspacepoint there is no child nodes (because they have dimensions). in current CR the code flow is somewhat different but we would have a default context with default dimensions and the sites node would have been found in that as well as the children. I think the ContentSubGraph that is used there is just wrong because it doesn't default to anything\Neos\EventSourcedNeosAdjustments\EventSourcedRouting\EventSourcedFrontendNodeRoutePartHandler::fetchSubgraphForParameters
Discussion with Bernhard:
$this->nodeService->generateUniqueNodeName($parent->findParentNode())
(see TODO)DocumentTitleNodeCreationHandler
: re-enable nodeUriPathSegmentGenerator (see TODO inside)(Bastian has started on that)
(WIP)
Maybe an idea: Primary events capture what the user "actually" did; and Derived events are generated e.g. to be able to watch a certain Node's visibility changes.
However, unsure to me what the correctness constraints on this are; and how to be able to guarantee eventual consistency in this case.
UPDATE: See #100 for a more detailed concept
In ContentStreamCommandHandler::handleForkContentStream()
we currently have to iterate over all events of a CS in order to determine its version.
Instead we should make the versions of the individual CS known to the ContentGraph
.
That would also be a requirement for #23
Discussion: #16
see comments in #43
this way, the Event Sourced CR should have NO dependencies on the ORM anymore!
Why is NodeIdentifier actually needed? example "SetProperty" - why is this using NodeIdentifier and not NodeAggregateIdentifier, DimensionSpacePoint, CSI?
Need to think through how the shine through with multiple DSPs should work / works........
Example where this breaks: PublishingService::getUnpublishedNodes -> not possible to create TraversableNode, because we are missing DSP.
The only change in CustomizedInternalRequestEngine is that we comment out $this->securityContext->clearContext(); for the session to prevail between different requests. Thsi needs to be cleaned up maybe a bit further.
Idea: Code complexity management; NOT further scalablity
Naming: "Constraint" // "Concern"?
is difficult to use and error-prone
should be done by #20
(Re)playing projections should never fail so possible invalid operations (due to failed soft constraint checks or bugs) should be ignored.
However we should log those cases in order to make them discoverable
I do not think we actually need these anymore; and they introduce ambiguity AFAIK.
(braindump)
Forking of content streams takes longer the more nodes exist (currently roughly 3 seconds for 50k nodes).
When publishing nodes partially this could lead to decreasing UX with larger growing projects.
At the "CR Sprint @ Dresden, April 2019" we collected some ideas on how to prevent this.
The approach we consider a good balance between performance & complexity rise is to pro-actively copy base content streams asynchronously into a "Content Stream Pool" so that we don't have to copy the Content Stream for every fork but can use a prepared one until the pool is used up.
Table in the form (simplified):
ReferenceContentStreamId | ContentStreamId |
---|---|
live-xyz | cs1 |
live-xyz | cs2 |
shared-xyz | cs3 |
Maintained by the GraphProjector
(see below)
ForkContentStream
=>
ReferenceContentStreamId
=> Content Stream to fork =>
0 results ?
=> create new ContentStreamId
else
=> use CSI from PoolContentStreamWasForked
with expect version = -1 (No Stream)ContentStreamWasForked
(cs
= Content Stream, v
= event version) =>
n
) (initially e.g. 5)if n == 0
=> dieelse
=>
n
times, each with a new CSI) of cs
=>
ContentStreamWasCopied(newCSI, referenceCSI)
with expect version v + 1
ContentStreamWasPartiallyCopied
with expect version v + m + 1
(m
= number of batches)ConcurrencyException
(= events have been published to cs
in the meantime) =>
ContentStreamCopyProcessWasIntercepted
=> "Restart" PMContentStreamWasForked
=>
ContentStreamWasCopied
=>
newCSI
(s) and referenceCSI
(s) to "Content Stream Pools" tableNodeWas...
(all content stream related events) =>
Hey everybody,
I have been thinking about creating a higher-level write-side API so people do not have to fiddle with the commands and correct identifiers etc for many cases.
My idea would be as follows:
NodeMutator
(or something similar to that) which you can create like NodeMutator::fromNode(NodeInterface $node)
NodeMutator
can be used like $mutator->setProperty(...)
which will then emit the SetProperty
Command.
MutationResponse
(or s.th. like this); where you e.g. could call block()
to ensure the projection has actually been updated. (Currently this would be a no-op until we introduce the async graph projection)$mutator->newChildNode()
-> returning a NodeBuilder
NodeBuilder
, to specify how your new node should look like..build()
; which will emit the CreateNodeAggregateWithNode
command. This will also return a new "NodeMutator" for the newly created node; so you can directly e.g. set properties for this.What do you think about it? :)
All the best,
Sebastian
See TODO comment in GraphProjector::whenNodesWereMoved() -> can be properly fixed with a testcase; the query to write is just difficult. So I am deferring this a bit (as #27 is already huge).
Additional case: a CHILD of a to be moved node is hidden; so it should keep its hidden state as well.
e.g. "does a node really have only a single parent?"
Implementation ticket: #13
I am yet unsure which approach to use for showing/hiding nodes.
(as suggested by Bernhard)
The idea is to capture the relationship between the user's intention (i.e. hiding a certain node); and the effects of that operation (i.e. all nodes which are now hidden because of this intention).
This would mean we have a separate DB table restrictionEdge
looking as follows:
i.e. for a tree of three nodes:
If I hide "a", I would get the edges "a->a" (to hide a itself), and the edges "a->b", "a->c"; all in their respective CS Identifiers / DSPs.
On forking a ContentStream, all these edges would need to be copied (similar to HierarchyEdges)
restrictionEdge
on CS, DSP and AffectedNodeAggregateIdentifierhierarchyEdge
Alternatively to materializing the restrictions at the write side, we could also check the access of nodes at query time.
While this may sound prohibitively expensive at first (if things are checked for every node), we
can probably spend things up a lot because the Nodes needed to render a single page are very
often highly-connected trees -- e.g. when rendering a menu, you need a certain subtree of Document Nodes; and when rendering content, you need a certain
subtree of content.
The idea now is that we only need to do this recursive checking when fetching the root of the
tree; and not when fetching leaves (as we then have all information readily consumable).
Hopefully, we can create a Cache in ContentSubgraph which allows to speed this up tremendously.
The idea is still pretty rough; but I'd like to discuss it to see if it is relevant.
We could also decide that the recursive checking is NOT done at all; but you are responsible
yourself to handle this in the application when fetching roots. This is actually pretty much
the (undefined) behavior of the old CR when checking this in detail.
-> node property should be called "_notInMenu" (or so) with underscore)
currently not consistent I'd say. either we use fully a whitelist, or we use the old handling.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.