Repository navigation
Add fallback interfaces to the object server - #2113
Conversation
252318b to
85ac9ae
Compare
zeenix
left a comment
There was a problem hiding this comment.
Changes requested.
Review by Codex on behalf of @zeenix.
The shared-instance fallback API fits the reported use case. One issue remains: ObjectManager omits inherited interfaces from children already registered in the object tree (inline finding).
85ac9ae to
94a063d
Compare
|
Generated by Claude Opus 5.5. Generated by Claude Code |
`ObjectServer` only dispatched a call to an interface registered at the exact path of the call, and replied with `UnknownObject` for any other path. A service thus had to register each of its objects up front, which it cannot do for objects whose paths are not known in advance, such as one object per ID, unit or session, and which is wasteful for objects only worth creating on demand. Replying to such calls outside of the object server is not an option either, as the object server replies to every method call once it runs. `ObjectServer::at_fallback` and `connection::Builder::serve_at_fallback` register an interface that serves its path and every path below it, unless that path has an interface of the same name of its own, or a closer ancestor has one registered as a fallback. This is what `dbus_connection_register_fallback` of libdbus and `sd_bus_add_fallback_vtable` of sd-bus provide. A path that only fallbacks serve is an object too, with the standard interfaces. `ObjectServer::interface` gets the interface that serves a path, be it a fallback. The objects registered below a fallback have it as well: their introspection data lists it, and an `ObjectManager` reports it for them, with its properties read at their paths, and emits `InterfacesAdded` and `InterfacesRemoved` as registrations change what serves them. The paths that only fallbacks serve are not enumerated, though. The same instance serves all those paths, so it learns the path of a method call from the header of the call, and that of a property access from the path of its signal emitter. Fixes z-galaxy#2112. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
Point to `ObjectServer::at_fallback` from the service chapter, for objects whose paths are not known in advance. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
`Connection::object_server` starts the task that listens for method calls in the background, and the connection drops the calls it reads before that task listens, so their callers never get a reply. A service that requests its well-known name after registering its interfaces is not affected, as nobody can call it through that name before then, and neither is one whose interfaces are registered through `connection::Builder::serve_at`, which has the object server listen before the connection reads any message. The peer of a peer-to-peer connection, or a caller of the unique name of the connection, can call in that window though. Document this, and point to the builder. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
94a063d to
0cd03fa
Compare
ObjectServeronly dispatches a call to an interface registered at the exact path of the call, and replies withUnknownObjectfor any other path. So a service cannot serve objects whose paths are not known in advance, such as one per ID, unit or session (systemd's unit templates, for example). Replying to such calls outside of the object server is not an option either, as the object server replies to every method call once it runs.ObjectServer::at_fallbackandconnection::Builder::serve_at_fallbackregister an interface that serves its path and every path below it, unless that path has an interface of the same name of its own, or a closer ancestor has a fallback of that name. This is what libdbus'dbus_connection_register_fallbackand sd-bus'sd_bus_add_fallback_vtableprovide. A path that only fallbacks serve is an object too:Properties,IntrospectableandPeerwork on it.ObjectServer::interfacegets the interface that serves a path, fallbacks included, with a signal emitter for that path. The one instance learns the path of a method call from its header, and that of a property access from its signal emitter. The service chapter of the book mentions the feature, with a link to the API docs.The objects registered below a fallback have it as well: their introspection data lists it, and an
ObjectManagerreports it for them, with its properties read at their paths, and emitsInterfacesAddedandInterfacesRemovedas registrations change what serves them.Left out on purpose: an instance per path (as with the
findcallback of sd-bus), and enumerating the paths that only fallbacks serve.The last commit is unrelated, and came up while testing this.
Connection::object_serverstarts listening for method calls in the background, and calls that arrive before then go unanswered. Services that request their name after registering their interfaces, or that useBuilder::serve_at, are not affected, but a caller of the unique name, or a peer-to-peer peer, can be. The commit documents that and points to the builder. I can split it out if you prefer.Fixes #2112.
Generated by Claude Opus 5.5.