resgateio / resgate

A Realtime API Gateway used with NATS to build REST, real time, and RPC APIs, where all your clients are synchronized seamlessly.
https://resgate.io
MIT License
685 stars 67 forks source link

Unable to resolve complex cyclic references #78

Closed jirenius closed 5 years ago

jirenius commented 5 years ago

Issue

Resgate handles resources with simple path cyclic reference, such as:

a -> b
b -> a

It fails to resolve more complex resource references, such as:

a -> b,c
b -> d
c -> d
d -> a,b

This is due to d having two cyclic paths (d->a->d and d->b->d), while Resgate only handle single path cycle.

Whenever such multi-path cycles are encountered, the connection requesting the resource will never get a response for the request as the resources will never be considered done loading.

Solution

Resgate needs to be able to handle more than a single path when resolving cyclic references.

jirenius commented 5 years ago

Recursion makes my head hurt!

Must investigate if it is possible to solve this way:

Replace Subscription.path []string with Subscription.paths [][]string, where new paths will be added for any call to wsConn.Subscribe, and not only the first, for as long as the Subscription resource is not yet Loaded.

Then, in Subscription.collectRefs in subscription.go, recursion should be checked against any of the paths to see if doneLoading may be called.

Note
Check if there is a need to have a "soft" doneLoading that is only for indirect reference, to prevent errors with racing for nested resources such as:

a -> b,c
b -> a
c ... slow responding.

Subscribing a would cause b and c to be subscribed.
When b is loaded, it would automatically call doneLoading as its reference a is a recursive one. If b is then subscribed directly before c is loaded, it will attempt to send a response to the client even if a is not yet complete as c has not yet loaded.

jirenius commented 5 years ago

Solved in #80