[PATCH 4/6] core: add message handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2017-10-02 at 14:32 +0200, Georg Chini wrote:
> On 02.10.2017 11:31, Tanu Kaskinen wrote:
> > On Sun, 2017-10-01 at 20:31 +0200, Georg Chini wrote:
> > > On 01.10.2017 18:16, Tanu Kaskinen wrote:
> > > > On Sat, 2017-08-19 at 17:48 +0200, Georg Chini wrote:
> > > > > +/* List handlers */
> > > > > +char *pa_core_message_handler_list(pa_core *c);
> > > > 
> > > > Putting this function to core-messages.h doesn't seem right to me. The
> > > > function will never be used outside core.c, so the it should be a
> > > > private function in core.c.
> > > > 
> > > 
> > > If I put it in core.c, I would need to expose the pa_core_message_handler
> > > structure, which you wanted to keep private.
> > 
> > I think it actually makes sense to make the struct public. It could be
> > private if it didn't have the description field, but since the handler
> > objects contain information that clients can query, they're similar to
> > all other core objects. I think it even makes sense to move the struct
> > to a separate message-handler.h header (but if you don't like that
> > idea, I'm fine with keeping it in core-messaging.h or moving it to
> > core.h).
> 
> You want a header file just for this struct? I would keep it in
> core-messages.h but if you prefer, I don't mind using a
> separate file.

Indeed, creating a separate header just for the struct definition
doesn't make much sense. After thinking this a bit more, I still like
the idea of having message-handler.[ch] for the message handler object,
 though. The message-handler.h header could include not only the struct
definition, but also the following functions:

pa_message_handler_new()
    (renamed from pa_core_message_handler_register())
pa_message_handler_free()
    (renamed from pa_core_message_handler_unregister)
pa_message_handler_set_description()
    (renamed from pa_core_message_handler_set_description())

The only thing left in core-messaging.h would be
pa_core_send_message(), and I'd move that to core.h.

But do as you like, I don't care about this that much.

> > Something that didn't occur to me when I reviewed this patch yesterday
> > is that the string that the list-handlers returns is tailor-made for
> > pactl/pacmd, which is not how the message handlers are expected to
> > behave. What if an application wants to not only print a message (of
> > which layout is already decided by the server), but to get a list of
> > handlers and do something else with that information?
> 
> I don't understand. Message handlers return a single string, so
> parsing the result is the task of the sender. The format returned
> by the handler is rather simple, apart from the header line
> it only consists of lines of the form
> 
> handler-path, " ", description
> 
> This should be easy to parse.

Not as easy as it would be with a standardized serialization format.

If we assume that the information that list-handlers returns is
basically a list of (path,description) pairs (which IMO is not a good
idea, I'll discuss that later), as an application developer I'd want to
be able to do this rather than dealing with the details of string
parsing:

const char *state = message_parameters;

if (pa_message_read_start_list(&state) < 0)
    fail("Expected a list.");

while (pa_message_read_end_list(&state) < 0) {
    char *path;
    char *description;

    if (pa_message_read_path(&state, &path) < 0)
        fail("Expected a path.");
    if (pa_message_read_string(&state, &description) < 0)
        fail("Expected a string.")

    /* Do something with path and description. */

    pa_xfree(description);
    pa_xfree(path);
}

The documentation becomes much simpler too. You don't need to describe
the string in detail (what are the separators, how to deal with
escaping etc.), this is sufficient to document the exact format of the
message:

    list-handlers
        parameters: none
        response: [Path String]

        The message returns all message handlers as a list. The list
        items contain the handler path and the handler description.

It can be explained just once how to read this notation. The
"parameters:" section describes the parameters of the message (in this
case there are none) and the "response:" section describes type of the
response parameters. Square brackets denote a list, and inside the
square brackets is the list item type (in this case the items consist
of a Path and a String value).

Now, on the topic why (path,description) pairs is not a very good idea:
choosing that structure assumes that message handlers won't have any
other properties in the future. We can't change the response format
specification, so it should be flexible enough so that we can add new
properties without breaking applications that were written before the
new properties existed.

If we use (path,description) pairs now, and for example add the handler
type (e.g. sink, loopback, etc) as a new property later, we'll have to
introduce a new message to be able to deal with that. Not ideal.

> > Also, it's questionable why the list-handlers command is implemented
> > with the messaging API in the first place. It's core functionality, so
> > why is it not implemented using the normal introspection API?
> 
> Two reasons:
> 
> a) It's much simpler than using the introspection API

Ok, but didn't we agree earlier that the messaging API is only meant
for modules, and new core features shall be added using the existing
API conventions? The rationale, if you've forgotten it, was that it's
annoying for application developers if the core API uses inconsistent
conventions and introspection functionality needs to be searched from
two different places.

I might accept it if you put the client-facing bits in the
introspection API, but use the messaging system behind the scenes. If
you want pursue that route, I'd like get an ok from Arun as well. This
is not only about the list-handlers message, it's about all future core
features.

Another possibility is to deprecate the whole introspection API and
reimplement it using the messaging API, but you probably don't want to
take such a big project.

> b) We should at least have one example in the code
> which shows how a message handler i implemented.

It's certainly good to have an example now so that we can discuss how
the message parameter serialization is supposed to work, but I don't
think we need to apply that example to master. I hope we'll have some
other example by the time 12.0 is released (IIRC, you plan to add a
message handler to module-loopback), but it's not a big deal if there
are no examples.

> > And one more thing: if the handler descriptions are visible to clients
> > and the descriptions are mutable, clients should be notified about
> > description changes.
> > 
> 
> How? Sending a signal?

A signal would be appropriate if the list-handlers operation is
implemented only as a message, but if it's implemented using the
introspection API, then the subscription system should be used for the
notifications.

Another thing that came to my mind is that notifications should also be
sent when message handlers are added and removed.

-- 
Tanu

https://www.patreon.com/tanuk


[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux