Skip to content

Act on the latest version of the resource state #91

@michielbdejong

Description

@michielbdejong

Just had a chat about this with @acoburn, I think there are a number of points where a Solid server should support concurrency of http requests. A naive but valid way of dealing with this is to queue up all http requests in a single queue at the gate, and only ever execute one at a time, to completion, before starting the next one. But of course that would be a bottleneck and most server implementations will probably want to do better than that. So another model is to have one such queue per resource, instead of a single queue for the whole server. Or maybe one queue for each pod / user.

One restriction we should probably specify is that the server should only report success if the authoritative state of a resource was deterministically updated. It doesn't mean that all cached copies have to be updated before the write request is completed, but they do need to update to the new authoritative state eventually.

Reads are pretty easy, they don't necessarily need to report the latest state of the server, as long as they report a state that is consistent with itself. So for instance if I PUT /foo, then PUT /bar, then GET /, then <> ldp:contains </foo> is ok even though it's outdated, but <> ldp:contains </bar> is incorrect.

There needs to be a single queue of operations that affect a given container, they can be:

  • add/remove a subcontainer
  • add/remove a non-container

There are also requests that affect more than one resource. I think with the deprecation of globbing and the rejection of recursive deletes, the remaining ones will be:

  • a PUT or DELETE affects both the resource itself and the container that contains it
  • a POST affects both the container itself and the resource that is created.
  • a PUT or POST to a non-existing resource will create all containers up to whatever parent does exist (mkdir-p)
  • a container DELETE which may conflict with a concurrent POST or a PUT

Note that mkdir-p might also conflict with PUT of a non-container.

For the same non-container resource, if PUT, PATCH, and DELETE requests can be handled concurrently, instead of having to handle those one-by-one from a single-file queue, that could greatly increase performance.

I think it's inevitable to introduce some concept of subtree locking to support all of this including mkdir-p. If we drop the requirement for server-side mkdir-p (move it to the client, basically), then concurrency becomes easier, and except for container delete (see below) you only ever have to lock either one resource, or two: a resource and the containment triple for it, in the container that directly contains it. Note that you don't have to lock the whole container, just the triple that pertains to the contained resource in question.

This leads to an attractive property: if two requests affect a different URL, then they can be handled concurrently without coordination.

For container deletion, we could say:
If the DELETE of a container starts at a where that container is not empty, then the server may refuse the request.

If the DELETE of a container starts at a where that container is empty, then if any concurrent requests create resource that make it non-empty, then the delete should overrule those new creations, and in that sense act as a recursive delete for those resources, without taking into account any ACL restrictions. So basically if a POST and a DELETE happen concurrently, both may report success to the client, but the DELETE will prevail.

Or if we don't make those two changes to the spec (removing the mkdir-p feature and relaxing the situation around container-deletion) then we need to state in the implementation guide that all POST, PUT and DELETE requests should lock not only the resource but also the containment triples they affect.

@acoburn I think that covers all the points of concurrency in the current spec, did I miss anything?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions