Issues with the presence service

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
Hi,

yesterday I got back most of the network related functionality in sugar.
It's still easy to break and needs cleanup. Anyway, here are some issues
I had:

- We need a way to get basic informations about the activity, before
joining it,  the title at very least. Might just use the service
properties for this? Maybe a get_title api in Activity?

Btw I'm somewhat confused by this in Activity:

def get_icon(self):
    return self._buddy.getIcon()

- We need a way to get the activity default type, so we can figure out
which activity to associate to the service.

- I had to make some hacky changes to share_activity. For udp services
we need to publish the group IP in the properties (unless there is a
better way?). Have a look at how I'm doing it currently... I'm sure we
can clean it up.

- There seem to be no way to join an activity other than manually
duplicate the service. Also should we provide this rather than have
every activity to reimplement it? In sugar.activity.Activity or maybe
even directly in the shell...

If there are already good ways to do these please correct me.

Marco

Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
- There are places where I want to pass services around through dbus. We
should use paths for this right? I couldn't find a way to recreate the
objects other than the protected _new_object though.

Marco
Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Dan Williams-4
On Thu, 2006-07-27 at 11:43 +0200, Marco Pesenti Gritti wrote:
> - There are places where I want to pass services around through dbus. We
> should use paths for this right? I couldn't find a way to recreate the
> objects other than the protected _new_object though.

That's intentional.

Just use the object path of the Service that the PS returned to you.  I
removed the service serialization stuff because the Service's object
path is essentially a pointer to the service, and that's what you send
to the PS to have it operate on.

Dan


Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Dan Williams-4
In reply to this post by Marco Pesenti Gritti
On Thu, 2006-07-27 at 11:41 +0200, Marco Pesenti Gritti wrote:
> Hi,
>
> yesterday I got back most of the network related functionality in sugar.
> It's still easy to break and needs cleanup. Anyway, here are some issues
> I had:
>
> - We need a way to get basic informations about the activity, before
> joining it,  the title at very least. Might just use the service
> properties for this? Maybe a get_title api in Activity?

Right; I guess we need to have the PS add some default attributes to the
activity advertisement.  We already do this for the "address" of the
service, since when you resolve the service you get the publisher's
address (unicast), not the communication address, which is a problem for
multicast services.

> Btw I'm somewhat confused by this in Activity:
>
> def get_icon(self):
>     return self._buddy.getIcon()

C&P error

> - We need a way to get the activity default type, so we can figure out
> which activity to associate to the service.

Right; I think we should do this locally.  We have to have something
like .desktop files, or hardcoded in the activities init routine, what
it's default type is.  We already do that when the activity registers
with the shell (I think?), so we need to allow the HomePage to access
that.  I'm not sure if the PS should know about the default type.

> - I had to make some hacky changes to share_activity. For udp services
> we need to publish the group IP in the properties (unless there is a
> better way?). Have a look at how I'm doing it currently... I'm sure we
> can clean it up.

Shouldn't the PS already be adding the "address" of the group into the
attributes of the message?  The address returned by get_address() on the
service should _always_ be the communication address of the service, not
the unicast address of the person who published it (which is what
get_source_address() is for).  I thought this worked already.

> - There seem to be no way to join an activity other than manually
> duplicate the service. Also should we provide this rather than have
> every activity to reimplement it? In sugar.activity.Activity or maybe
> even directly in the shell...

Well, we _have_ to create a new service when we join the activity, since
we need to change the source address for the service anyway.  Even if we
receive a service from the network from somebody else, that service is
"somebody else's" service, and _not_ ours.  We have to create a new
service, cloned from the original service, and publish that instead,
because that uses our local information.

Dan


Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
In reply to this post by Dan Williams-4
Dan Williams wrote:

> On Thu, 2006-07-27 at 11:43 +0200, Marco Pesenti Gritti wrote:
>  
>> - There are places where I want to pass services around through dbus. We
>> should use paths for this right? I couldn't find a way to recreate the
>> objects other than the protected _new_object though.
>>    
>
> That's intentional.
>
> Just use the object path of the Service that the PS returned to you.  I
> removed the service serialization stuff because the Service's object
> path is essentially a pointer to the service, and that's what you send
> to the PS to have it operate on.
>  
I'm not sure to understand this.... The use case is:

1 I have a sugar.presence.Activity in the shell
2 I want to pass it to an activity (different process) through dbus. I
currently do this with activity.object_path().
3 From the activity process I want to call sugar.presence.Activity
methods (get_id, get_services etc). To be able to do it I need to
'recreate' the object from his path. And I'm doing it using _new_obj.

What is the correct way to do this?

I possibly misunderstood your comment in irc about using object paths...
maybe the activity_id should be used for this instead?

Thanks,
Marco
Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
In reply to this post by Dan Williams-4

>> - We need a way to get the activity default type, so we can figure out
>> which activity to associate to the service.
>>    
>
> Right; I think we should do this locally.  We have to have something
> like .desktop files, or hardcoded in the activities init routine, what
> it's default type is.  We already do that when the activity registers
> with the shell (I think?), so we need to allow the HomePage to access
> that.  I'm not sure if the PS should know about the default type.
>
>  

We are already doing this locally... I think we need to advertise it in
the PS though. Otherwise how  do you associate the right activity icon
in the home page for remote activities (published by someone and not
joined) ? And, more importantly, how do you open a remote activity if
you don't know his type?

>> - I had to make some hacky changes to share_activity. For udp services
>> we need to publish the group IP in the properties (unless there is a
>> better way?). Have a look at how I'm doing it currently... I'm sure we
>> can clean it up.
>>    
>
> Shouldn't the PS already be adding the "address" of the group into the
> attributes of the message?  The address returned by get_address() on the
> service should _always_ be the communication address of the service, not
> the unicast address of the person who published it (which is what
> get_source_address() is for).  I thought this worked already.
>
>  

That make sense now. Though I think it was not working... a bug
somewhere I guess.

>> - There seem to be no way to join an activity other than manually
>> duplicate the service. Also should we provide this rather than have
>> every activity to reimplement it? In sugar.activity.Activity or maybe
>> even directly in the shell...
>>    
>
> Well, we _have_ to create a new service when we join the activity, since
> we need to change the source address for the service anyway.  Even if we
> receive a service from the network from somebody else, that service is
> "somebody else's" service, and _not_ ours.  We have to create a new
> service, cloned from the original service, and publish that instead,
> because that uses our local information

Right, my point was more than we need convenient way to do it (and one
that doesn't need a comment to clarify what is going on)...

                # Ok, there's an existing chat service that we copy
                # parameters and such from
                addr = service.get_address()
                port = service.get_port()
                self._chat_service =
self._pservice.share_activity(self._activity,
                                stype=ActivityChat.SERVICE_TYPE,
address=addr, port=port)

Btw, this is missing in the browser activity atm. We need to fix that...
(or provide this for every activity).

Thanks,
Marco
Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Dan Williams-4
In reply to this post by Marco Pesenti Gritti
On Sat, 2006-07-29 at 14:05 +0200, Marco Pesenti Gritti wrote:

> Dan Williams wrote:
> > On Thu, 2006-07-27 at 11:43 +0200, Marco Pesenti Gritti wrote:
> >  
> >> - There are places where I want to pass services around through dbus. We
> >> should use paths for this right? I couldn't find a way to recreate the
> >> objects other than the protected _new_object though.
> >>    
> >
> > That's intentional.
> >
> > Just use the object path of the Service that the PS returned to you.  I
> > removed the service serialization stuff because the Service's object
> > path is essentially a pointer to the service, and that's what you send
> > to the PS to have it operate on.
> >  
> I'm not sure to understand this.... The use case is:
>
> 1 I have a sugar.presence.Activity in the shell
> 2 I want to pass it to an activity (different process) through dbus. I
> currently do this with activity.object_path().
> 3 From the activity process I want to call sugar.presence.Activity
> methods (get_id, get_services etc). To be able to do it I need to
> 'recreate' the object from his path. And I'm doing it using _new_obj.

Ah, I understand.  Two ways, like you suggest.  In both cases, the other
Activity process needs to have a PresenceService object (from
sugar.presence.PresenceService) created for itself.

Solution 1:
Pass the object path from the Shell to the other activity process
through dbus (use type 'o' for object paths rather than type 's' so they
get validated correctly).  Add a "get()" call (or something like that)
to the sugar.presence.PresenceService object that creates the
Python-wrapped D-Bus object, and return it.  Pass the object path into
get().

Solution 2:
Just pass the activity ID, and then call the
sugar.presence.PresenceService's get_activity() method.  However, this
isn't generic and therefore there's no easy way to get a Service or
Buddy object, for example.

I vote for #1 I guess.  There's a benefit to making IPC and RPC
dead-easy for kids to do, but there's a minimal level of complexity with
IPC/RPC anyway that we simply can't cover over.

Dan

> What is the correct way to do this?
>
> I possibly misunderstood your comment in irc about using object paths...
> maybe the activity_id should be used for this instead?
>
> Thanks,
> Marco

Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Dan Williams-4
In reply to this post by Marco Pesenti Gritti
On Sat, 2006-07-29 at 15:05 +0200, Marco Pesenti Gritti wrote:

> >> - We need a way to get the activity default type, so we can figure out
> >> which activity to associate to the service.
> >>    
> >
> > Right; I think we should do this locally.  We have to have something
> > like .desktop files, or hardcoded in the activities init routine, what
> > it's default type is.  We already do that when the activity registers
> > with the shell (I think?), so we need to allow the HomePage to access
> > that.  I'm not sure if the PS should know about the default type.
> >
> >  
>
> We are already doing this locally... I think we need to advertise it in
> the PS though. Otherwise how  do you associate the right activity icon
> in the home page for remote activities (published by someone and not
> joined) ? And, more importantly, how do you open a remote activity if
> you don't know his type?

Well, you can't join the activity if you don't have that activity
locally already (though we need to figure out how to get the activity
from another child if you don't have it).  It's also completely useless
advertise the activity type if you don't have the activity code locally
too, since you have to have the activity code locally to be able to
display that activity.

Like icons; if you don't have the icon for .doc files, it shows up as a
blank one.  I don't see how publishing the activity type is not like
this.  If you have the activity locally already, the activity itself
will be able to register all the types it handles with the PS, so that
the PS can tell the activity when new instances appear.

I don't think this has anything to do with the PS.  The Home Page is
more of a document viewer, and activities will have to "register" their
type and how to handle it with the Home Page.  Trying to add that to the
PS seems like unnecessary complication to me, when all the rendering is
done in the home page anyway.

So how about this for a flow?

- PS sees new "_tamtam._tcp" service advertised, sends ServiceAppeared
signal

- Home Page receives ServiceAppeared signal, looks through it's registry
for Activities that can handle "_tamtam._tcp"

- Home Page finds the TamTam activity can handle it, and asks some
TamTam code to thumbnail and display the activity on the Home Page

My point is that on the activities _themselves_ can know what service
types the can handle, and how to handle those types.  We don't need a
"default type" passed through the PS, because the local activity knows
how to handle it.  For example, the browser uses "_web_olpc._udp" and
"_olpc_model._tcp".  The Browser activity already knows that the
_web_olpc._udp service is the "default" service for a browser activity,
and it can tell the Home Page that without the PS getting involved.

>
> >> - I had to make some hacky changes to share_activity. For udp services
> >> we need to publish the group IP in the properties (unless there is a
> >> better way?). Have a look at how I'm doing it currently... I'm sure we
> >> can clean it up.
> >>    
> >
> > Shouldn't the PS already be adding the "address" of the group into the
> > attributes of the message?  The address returned by get_address() on the
> > service should _always_ be the communication address of the service, not
> > the unicast address of the person who published it (which is what
> > get_source_address() is for).  I thought this worked already.
> >
> >  
>
> That make sense now. Though I think it was not working... a bug
> somewhere I guess.

I did change that code somewhat from the previous in-process PS
implementation, and it's somewhat complicated.  So there may be a bug.

> >> - There seem to be no way to join an activity other than manually
> >> duplicate the service. Also should we provide this rather than have
> >> every activity to reimplement it? In sugar.activity.Activity or maybe
> >> even directly in the shell...
> >>    
> >
> > Well, we _have_ to create a new service when we join the activity, since
> > we need to change the source address for the service anyway.  Even if we
> > receive a service from the network from somebody else, that service is
> > "somebody else's" service, and _not_ ours.  We have to create a new
> > service, cloned from the original service, and publish that instead,
> > because that uses our local information
>
> Right, my point was more than we need convenient way to do it (and one
> that doesn't need a comment to clarify what is going on)...
>
>                 # Ok, there's an existing chat service that we copy
>                 # parameters and such from
>                 addr = service.get_address()
>                 port = service.get_port()
>                 self._chat_service =
> self._pservice.share_activity(self._activity,
>                                 stype=ActivityChat.SERVICE_TYPE,
> address=addr, port=port)

Hmm, maybe we should make the Activity base class handle the sharing?
Because Activity objects already know their default service type, and we
shouldn't be using "share_activity" to publish anything _except_ the
default service type.

I wanted to get away from having create_service()/create_activity()
calls that just create the service/activity and then wait for you to do
something with it.  That's pretty useless and encourages bad habits.
When you create a service, it should be published automatically because
there's no legitimate reason I can think of that it shouldn't be
published automatically.

Dan


Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
In reply to this post by Dan Williams-4
Dan Williams wrote:

> On Sat, 2006-07-29 at 14:05 +0200, Marco Pesenti Gritti wrote:
>  
>> Dan Williams wrote:
>>    
>>> On Thu, 2006-07-27 at 11:43 +0200, Marco Pesenti Gritti wrote:
>>>  
>>>      
>>>> - There are places where I want to pass services around through dbus. We
>>>> should use paths for this right? I couldn't find a way to recreate the
>>>> objects other than the protected _new_object though.
>>>>    
>>>>        
>>> That's intentional.
>>>
>>> Just use the object path of the Service that the PS returned to you.  I
>>> removed the service serialization stuff because the Service's object
>>> path is essentially a pointer to the service, and that's what you send
>>> to the PS to have it operate on.
>>>  
>>>      
>> I'm not sure to understand this.... The use case is:
>>
>> 1 I have a sugar.presence.Activity in the shell
>> 2 I want to pass it to an activity (different process) through dbus. I
>> currently do this with activity.object_path().
>> 3 From the activity process I want to call sugar.presence.Activity
>> methods (get_id, get_services etc). To be able to do it I need to
>> 'recreate' the object from his path. And I'm doing it using _new_obj.
>>    
>
> Ah, I understand.  Two ways, like you suggest.  In both cases, the other
> Activity process needs to have a PresenceService object (from
> sugar.presence.PresenceService) created for itself.
>
> Solution 1:
> Pass the object path from the Shell to the other activity process
> through dbus (use type 'o' for object paths rather than type 's' so they
> get validated correctly).  Add a "get()" call (or something like that)
> to the sugar.presence.PresenceService object that creates the
> Python-wrapped D-Bus object, and return it.  Pass the object path into
> get().
>
> Solution 2:
> Just pass the activity ID, and then call the
> sugar.presence.PresenceService's get_activity() method.  However, this
> isn't generic and therefore there's no easy way to get a Service or
> Buddy object, for example.
>
> I vote for #1 I guess.  There's a benefit to making IPC and RPC
> dead-easy for kids to do, but there's a minimal level of complexity with
> IPC/RPC anyway that we simply can't cover over.
>  

#1 sounds good to me too. This shouldn't be something frequently needed
for writing activities anyway.

Marco
Reply | Threaded
Open this post in threaded view
|

Issues with the presence service

Marco Pesenti Gritti
In reply to this post by Dan Williams-4

> So how about this for a flow?
>
> - PS sees new "_tamtam._tcp" service advertised, sends ServiceAppeared
> signal
>
> - Home Page receives ServiceAppeared signal, looks through it's registry
> for Activities that can handle "_tamtam._tcp"
>
> - Home Page finds the TamTam activity can handle it, and asks some
> TamTam code to thumbnail and display the activity on the Home Page
>
> My point is that on the activities _themselves_ can know what service
> types the can handle, and how to handle those types.  We don't need a
> "default type" passed through the PS, because the local activity knows
> how to handle it.  For example, the browser uses "_web_olpc._udp" and
> "_olpc_model._tcp".  The Browser activity already knows that the
> _web_olpc._udp service is the "default" service for a browser activity,
> and it can tell the Home Page that without the PS getting involved.
>  

Ah! I had forgot the default type is just the name of the default
service... I need a new brain.

>  
>>>> - There seem to be no way to join an activity other than manually
>>>> duplicate the service. Also should we provide this rather than have
>>>> every activity to reimplement it? In sugar.activity.Activity or maybe
>>>> even directly in the shell...
>>>>    
>>>>        
>>> Well, we _have_ to create a new service when we join the activity, since
>>> we need to change the source address for the service anyway.  Even if we
>>> receive a service from the network from somebody else, that service is
>>> "somebody else's" service, and _not_ ours.  We have to create a new
>>> service, cloned from the original service, and publish that instead,
>>> because that uses our local information
>>>      
>> Right, my point was more than we need convenient way to do it (and one
>> that doesn't need a comment to clarify what is going on)...
>>
>>                 # Ok, there's an existing chat service that we copy
>>                 # parameters and such from
>>                 addr = service.get_address()
>>                 port = service.get_port()
>>                 self._chat_service =
>> self._pservice.share_activity(self._activity,
>>                                 stype=ActivityChat.SERVICE_TYPE,
>> address=addr, port=port)
>>    
>
> Hmm, maybe we should make the Activity base class handle the sharing?
> Because Activity objects already know their default service type,

I think we should do that.
Btw there is join_activity/joinActivity in shell/PresenceService which
seem to be unused?

> and we
> shouldn't be using "share_activity" to publish anything _except_ the
> default service type.
>
>  

I think that's not the case at the moment... so we should fix it.

There are probably other cases where you will want to "clone and
republish" a service. That might not be frequent enough to deserve a
specific API though, not sure.

> I wanted to get away from having create_service()/create_activity()
> calls that just create the service/activity and then wait for you to do
> something with it.  That's pretty useless and encourages bad habits.
> When you create a service, it should be published automatically because
> there's no legitimate reason I can think of that it shouldn't be
> published automatically.
>  

Yeah, that make sense.

Seems like we covered pretty much everything. We just need to go through
this thread and fix up stuff...

Thanks,
Marco