← Back to team overview

launchpad-dev team mailing list archive

Re: Want feedback on LaunchpadSharp

 

On 5/5/2010 12:05 AM, Leonard Richardson wrote:
<snip>

I don't know any C#, so I don't understand what happens inside
wadlsharp, but I believe your problems start there, with the generation
of C# client code for later customization. I'm looking at
LpClientProxy.cs in lpsharp, and it looks like it's the output of
wadlsharp, or some wadlsharp-aided transformation of the WADL served by
Launchpad on a specific date.

Yes. It uses WadlConverter.Convert(wadlFileName,csFileName, rootNamespace) method to create the client proxy.

> From what I can see about the way lpsharp works, lpsharp scripts that do
not use the modified feature will still work. But, lpsharp scripts that
do use the feature will break, and these scripts _cannot be fixed_
without upgrading lpsharp and _then_ rewriting the script. Because the
lpsharp code was generated from an old version of the WADL, lpsharp has
no way to find out what the new service looks like.

Oh! That would seriously break the whole library/application.

2. OK, now imagine that we add a backwards-compatible improvement to the
web service. You don't really have to imagine this because we do it all
the time. Looking at the service_root_json class in LpClientProxy.cs, I
see members like:

...
private string _pillars_link;
private string _translation_import_queue_entries_collection_link;
private string _bug_trackers_collection_link;
private string _countries_collection_link;
...

For (almost) any one of these links, there was a time in the past year
when the web service did not publish that link. The same is true for
(almost) all the named operations defined in LPClientProxy.cs as
people_findPerson, etc. When we add anything new to the web service,
existing installations of launchpadlib will pick up on it. Existing
installations of lpslash will not.

People have a gripe about WADL that is breaks the RESTful model. I find RESTful model easier to implement on interpreted languages, but for C# or any CLI based language, it can be a bit tough.

Even sometimes I feel that WADL introduces a lot of hardcoding in the service description. The only way left to mitigate is to generate the client code on the fly as you mentioned below in next point.

3. Currently there are three versions of the Launchpad web service:
"beta", "1.0" and "devel". Each publishes a slightly (or drastically)
different WADL document. This is how we're able to make the strong
promises we make about backwards compatibility (see #1).

launchpadlib's Launchpad constructor takes a version name, and reads
(from the server or from a cache) the appropriate WADL document at
startup. If there are 5 versions of the web service, there can be up to
5 cached WADL documents on the user's hard drive, but there's only one
copy of launchpadlib. Five pieces of data, one piece of code.

I like this idea. Really an eye-opener. I don't think any huge and drastic change needs to be done nor the older codebase needs to be thrown off.

= Suggestions =

OK, what is the alternative? I suggest that you think of lpsharp not as
a C# "wrapper" for Launchpad's web service, but as a "client" or
"browser" that happens to be scriptable through C#. That's kind of
abstract, but I mean this: consider the WADL file as a piece of data to
be consumed at runtime, rather than as a template for code generation.

Got it. This means the code should be generated at runtime? Right? I think this approach is even better and more easy to implement than the current way. I need to write one more library/project which just takes the WADL and generates the dynamic library dll/so for that which can be consumed by the application.

I appreciate that C# is a compiled language, and code generation seems
like a better alternative in a compiled language. I don't know if it's
possible to implement something like __getattr__() in C#--that's the
fundamental technology underlying launchpadlib, and nobody wants to
write launchpad['people'] or launchpad.get('people') instead of
launchpad.people.

It is possible. It too has a concept of Reflection. All types can be accessed even at runtime which includes probing for methods, constructors, properties, field etc.

If code generation really is the only way to make a reasonable C#
client, I suggest you generate the code at runtime, keep it cached
alongside the WADL file, and regenerate it whenever you start up lpslash
and discover that the WADL has changed. But, I don't know if that's
possible either! It might be too complicated or violate a C# security
policy.

Sure. Next I am going to work on that. I think that can be a better way. Initially it might be a pain to start with, though future maintaince would be pretty easy. Reflection is a bit tough, but atleast I know how to use the WADL file when generating the code using CodeDom. I know which nodes corrosponds to what and which node has what significance and any cross-references (if-any)

To sum up: You will definitely be able to create a launchpadlib-like
client using the architecture you have now. But the value of an lpslash
installation will decline over time unless it's kept updated, whereas a
launchpadlib installation maintains its value over time.

I can understand that. There is a trade-off between cheaply created codebase and maintainability. I would prefer the latter. Gimme me two more weeks and I would come up with runtime generated implementation.

I need to learn a bit about Reflection as I started using C# only a few months back due to my work requirements. I like to hack on Python, but I wanted Launchpad to be available using more than one language.

Please let me know your thoughts, and feel free to ping me on IRC
(leonardr) so we can discuss this in real time.

Thanks a lot Leonard for the lengthy and patient reply. Your views are highly valuable and informative. I would surely come on IRC once I get time. Since my brother is coming this weekend, I would be bit busy and would ping you next week.


--
Manish Sinha
http://launchpad.net/~manishsinha



References