Bug 26059 - Requests Mixin doesn't create Handles on demand
Summary: Requests Mixin doesn't create Handles on demand
Status: RESOLVED MOVED
Alias: None
Product: Telepathy
Classification: Unclassified
Component: tp-python (show other bugs)
Version: git master
Hardware: Other All
: medium normal
Assignee: Telepathy bugs list
QA Contact: Telepathy bugs list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-15 04:06 UTC by Ed Page
Modified: 2019-12-03 20:14 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description Ed Page 2010-01-15 04:06:36 UTC
Version: 0.15.13-1

Reproduction Steps:

1. In a telepathy client (tested in RTComm) the user selects "Send IM To"
2. The user enters the contact identifier for someone not on the
contact list (so no previous handles created)

Expected Outcome:

1. Clients will call ConnectionInterfaceRequests.CreateChannels with
TargetHandleId set as the contact name.
2. CreateChannels (through _alter_properties) calls an internal
equivalent of RequestHandles to get a TargetHandle for the
TargetHandleId, creating a new handle if needed.

Actual Outcome:

1. Clients will call ConnectionInterfaceRequests.CreateChannels with
TargetHandleId set as the contact name.
2. CreateChannels (through _alter_properties) searches among existing
handles, checking if the "get_name() == TargetHandleId"
3. The handle has not previously been created and an exception is raised

Notes:

This puts on the requirement that the handle had to already exist
which makes calling without a TargetHandle pointless.
Handle.get_name() is checked directly against user input, not allowing
CM implementers to normalize the names that come in
When constructing the exception that gets thrown for an invalid
contact, the string formatting is setup incorrectly and a different
exception will be thrown instead.

Fix:

I've branched the latest Master of telepathy-python.  I extracted code
from the default implementation of RequestHandles and made it a
function called "get_handle_by_name".  I then made the requests
interface call that.   As a parallel function, I also implemented
"get_handle_by_id" which is a simplistic function that clients are
expected to implement for the Channel mixins (previously the channel
mixins called it "handle" which I found quite an ambiguous name).
git://github.com/epage/telepathy-python.git
Comment 1 Ed Page 2010-01-27 19:06:05 UTC
Note that a fix was pulled from an earlier date in my branch which ... hadn't actually been tested.  My branch now has the latest version with various fixes to it.

The branch also as a single commit for Bug 26289
Comment 2 Jonny Lamb 2010-04-16 14:50:09 UTC
Sorry for taking so long to get back to you about this.

I've cherry-picked the relevant commits from your branch and created a new one for ease of review, although I might just squash them all into one:

http://git.collabora.co.uk/?p=user/jonny/telepathy-python.git;a=shortlog;h=refs/heads/26059

Here's a quick review:

Why did you implement get_handle_by_name? Why not just use RequestHandles and require that it returns Handle objects (or subclasses). The problem I foresee here is that butterfly expects all its handles to be of type ButterflyHandle. This works because it re-implements RequestHandles. What we could do is something like this:

-            ret.append(handle.get_id())
+            ret.append(handle)

in RequestHandles, and add a __int__() method to telepathy.server.Handle which returns the same as get_id(). What do you think? It sounds like a cleaner solution and nicer to CMs using tp-python (we've got to give them something!)

This solution would also mean that bug #27445 could be fixed in tp-python instead of butterfly which is cool. Thoughts?
Comment 3 Ed Page 2010-04-16 15:58:44 UTC
(In reply to comment #2)
> Why did you implement get_handle_by_name?

I actually use get_handle_by_name in several parts of The One Ring.
1. When i need a single item its nicer to get it than handle the list case
2. I imagine CMs would not normally specialize the boilerplate in RequestHandles but just what is exactly in get_handle_by_name
3. Maybe its a lack of knowledge in how the dbus bindings work but I feel weird internally calling into the external API
4. I'm not too sure what all cases handles should be marked as client handles but its nicer to have a call under the hood for when a handle isn't a client handle

> Why not just use RequestHandles and
> require that it returns Handle objects (or subclasses). The problem I foresee
> here is that butterfly expects all its handles to be of type ButterflyHandle.
> This works because it re-implements RequestHandles. What we could do is
> something like this:
> -            ret.append(handle.get_id())
> +            ret.append(handle)
> 
> in RequestHandles, and add a __int__() method to telepathy.server.Handle which
> returns the same as get_id(). What do you think? It sounds like a cleaner
> solution and nicer to CMs using tp-python (we've got to give them something!)
> 
> This solution would also mean that bug #27445 could be fixed in tp-python
> instead of butterfly which is cool. Thoughts?

I think this change makes sense independent of whether get_handle_by_name is used or not.
Comment 4 Jonny Lamb 2010-04-16 16:11:24 UTC
(In reply to comment #3)
> I actually use get_handle_by_name in several parts of The One Ring.
> 1. When i need a single item its nicer to get it than handle the list case

Right, butterfly has a handle factory it uses throughout.

> 2. I imagine CMs would not normally specialize the boilerplate in
> RequestHandles but just what is exactly in get_handle_by_name
> 3. Maybe its a lack of knowledge in how the dbus bindings work but I feel weird
> internally calling into the external API

By external API do you mean methods like RequestHandles? Overriding such methods is completely normal.

My point is that the CM-specific work has already been done in redefining RequestHandles -- butterfly does it[0] and sunshine does it[1]. It would be nice to not have to have further CM-specific handle functions and re-use the ones we already have, no?

0. http://git.collabora.co.uk/?p=telepathy-butterfly.git;a=blob;f=butterfly/connection.py;hb=HEAD#l251
1. http://git.collabora.co.uk/?p=telepathy-sunshine.git;a=blob;f=sunshine/connection.py;hb=HEAD#l370
Comment 5 Ed Page 2010-04-16 16:55:55 UTC
(In reply to comment #4)
> Right, butterfly has a handle factory it uses throughout.

For sunshine, butterfly, the one ring, and my pre-alpha bluewire the handle factory does one thing and exactly one thing, create a handle using handletype specific parameters.

In my view get_handle_by_name translates handle_type/name to a handle object.  I think that translation logic from name to handle init parameters belongs in get_handle_by_name rather than the handle factory.  I used to (no need anymore) and butterfly currently does translation between name and handle init parameters.

Having the logic decoupled is nice for when your protocol initiates the creation of a handle.  You already have the disparate parameters.  Its annoying to construct them into a name just to have the handle factory decompose them again into distinct parameters.
 
> By external API do you mean methods like RequestHandles? Overriding such
> methods is completely normal.

Hmm, my reference in my comment to "external API" was not about overriding but calling them from within my own CM.  My problems are
1. A personal lack of understanding of dbus bindings and any magic it might do to the function
2. proper layering
3. keeping the code more decomposed so I don't call these monoliths that do more than I want.

> My point is that the CM-specific work has already been done in redefining
> RequestHandles -- butterfly does it[0] and sunshine does it[1]. It would be
> nice to not have to have further CM-specific handle functions and re-use the
> ones we already have, no?
> 
> 0.
> http://git.collabora.co.uk/?p=telepathy-butterfly.git;a=blob;f=butterfly/connection.py;hb=HEAD#l251
> 1.
> http://git.collabora.co.uk/?p=telepathy-sunshine.git;a=blob;f=sunshine/connection.py;hb=HEAD#l370

Compared to my branch of tp-python, what parts are butterfly and sunshine overriding?  Not the whole function.  Its the part of the code in the for-loop and that is the code I propose be moved into get_handle_by_name.  I would not want get_handle_by_name to be added just for me but I would expect other CMs to enjoy my very abstract benefits from it ;)

I noticed sunshine has get_handle_id_by_name.  The two main differences are
1. It returns an id rather than an object
2. It only searches rather than doing a search and a construction.

I can understand wanting (2) and could see this being decomposed in a different way.
Comment 6 GitLab Migration User 2019-12-03 20:14:16 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/telepathy/telepathy-python/issues/10.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.