MDSLab / s4t-lightning-rod

Implementation of the Lightning-rod, the Stack4Things node-side probe (this version works with the standalone version of IoTronic)
http://stack4things.unime.it/
Apache License 2.0
3 stars 8 forks source link

Plugin/call confusion - new terminology proposal #33

Closed KostyaEsmukov closed 7 years ago

KostyaEsmukov commented 8 years ago

Hello,

I guess there is a confusion between the call and plugin types of plugins.

I propose to introduce the next terminology:

Please let me know what do you think of this.

Kostya.

KostyaEsmukov commented 8 years ago

Also a bit off topic, but why do plugins not contain the license header?

KostyaEsmukov commented 8 years ago

Now I see that every plugin has a corresponding call_*, which does the same, but once (non-periodically). Does it mean that every plugin should support a single "call" functionality? In this case there's no need in such terminology at all - we will just make every plugin implement start and call methods.

KostyaEsmukov commented 8 years ago

Oh, well, not every plugin :)

KostyaEsmukov commented 8 years ago

OK then, I feel that start/call methods overriding approach is the most convenient here. As for plugins/calls without corresponding pairs above, absent (non-overriden) methods would raise an exception, similar to absent call_* or *_plugin files. So, in that case, that terminology introduced above is not needed.

Please let me know what do you think of this.

flongo82 commented 8 years ago

Hi Kostya, sorry for late reply. So the semantics here is as follows:

Of course, on top of this other behaviors can be implemented. For example, asynchronous plugins can be "killed" if for some reason they cannot be stopped or "restarted" if I want to stop and start again a plugin. Also synchronous plugins can be "killed" if they stuck after being called (of course the "call" call would in that case timeout).

Hope this is clearer. Of course we can try to find any model that captures all these behaviors but I would simply define two types of plugins with different calls.

What do you think?

KostyaEsmukov commented 8 years ago

Hi Francesco,

It's much clearer now, thank you!

From the point of code reuse and flexibility, it would be better if plugins will simply inherit the base plugin class and implement functionality that they should provide.

Actually I've already implemented such approach locally (not pushed yet) and it looks pretty convenient. Of course I'll be looking forward for your comments! I guess it's better to discuss a real code rather than some abstract terms ;)

flongo82 commented 8 years ago

As you can see from examples, plugins are really just a Node.js module in which you have a specific "main" function which is the one that is "called" or "started" depending on the kind of plugins.

Of course we were also thinking about extending a little bit the plugin framework so that each plugin (I think it makes sense more for synchronous ones) can implement more functions that are then exposed as REST calls on the Cloud side. In that case I can pass to the "call" REST call the name of the function I want to be run.

However, there was no notion of base plugin class from which each plugin needs to inherit.

@npeditto am I explaining everything correctly?

KostyaEsmukov commented 8 years ago

Pushed. See the linked commit. Please take a look ASAP and decide whether I should keep it this way or not, thank you.

KostyaEsmukov commented 8 years ago

Also please let me know whether plugins should contain the license header or not.

flongo82 commented 8 years ago

Hi Kostya, I had a look at your code. My feeling is that inheritance could be a good idea that can be exploited in some way in our use case but it seems to me that the way you did is against our initial use case requirements.

In our idea the Stack4Things Cloud implements both an IaaS Cloud extended with Internet of things resources and a PaaS Cloud that allows the developer to inject plugins in the IoT nodes.

A developer who wants to implement a new plugin and inject it in the Cloud and then into a node first of all needs to decide if the plugin is synchronous or asynchronous. It cannot be both. Then, she only needs to implement a single method (the main method) putting inside the main all the logic that she needs. She can also implement other methods that can be called from the main method but the Cloud does not know about them. The Cloud only knows about the main menu that is called when the plugin is started. If the plugin is a asynchronous one the main method is not supposed to return anything and it is supposed to be long-running (but it could also not be long-running). If the plugin is a synchronous one the main method is supposed to return a JSON and it is supposed to be short-running (withing HTTP timeouts).

In your case it seems to me that the developers can implement both synchronous and asynchronous methods. This is wrong.

Probably the better way to keep part of your work is to implement two classes (asynchronous and synchronous plugins) and let the developer inherit from one of the two.

KostyaEsmukov commented 8 years ago

Thank you for your response.

Given that plugin can't be both synchronous or asynchronous at the same time, I agree that my current solution contradicts with that requirement. I'm sorry I haven't figured it out. I'll surely introduce two base classes as you suggest. I'll call them SynchronousPlugin and AsynchronousPlugin - I guess that would be clear for developers.

The only thing I'm concerned about is the duplicated code in example plugins (like call_hum and hum_plugin, etc). May I move such code out to make it look like base_hum, async_hum, sync_hum?

PS Well, I guess that the license headers were missing unintentionally ;-)

flongo82 commented 8 years ago

The developer is supposed to upload just one file with a complete and self-contained Node.js module.

So no, you cannot separate the plugin in more than one file.

Yes, the licence headers were missing unintentionally because the plugins on which you are working are just examples so it was not important to put a licence on them.

KostyaEsmukov commented 8 years ago

Ok, I understand your position.

I see three options:

  1. Leave a single type of plugin for each duplicated one. I guess this is the best option.
  2. Introduce a build system that will produce a single js file from the multiple ones. This is the most elegant solution, though a bit tricky one.
  3. Leave it as is - a copypasted code. This is an ugly solution, because LR developers must know for sure that the code they edit is duplicated somewhere and must be edited the same way. This violently contradicts with the DRY principle.

I suggest to go with the first option. Please let me know what do you think about it.

flongo82 commented 8 years ago

Ok, I realized you are probably missing the whole picture here.

Plugins are not written by Stack4Things developers. Plugins are written by Stack4Things users. A user of Stack4Things is an IoT infrastructure administrator and/or an IoT application developer who wants to:

i) write her own plugins, i.e., pieces of logic that do something ii) inject the plugins into the Stack4Things Cloud iii) deploy the plugins into one or more nodes connected to the Cloud

Plugins has to be single Node.js module (this could in principle be changed but right now we went for the simpler solution) so if, while writing their plugins, Stack4Things users want to respect DRY principle then it will be their responsibility to use, for example, your option number 2.

Again, I suggest you skip the folder plugin.examples. That is not part of the LR code. In fact, as you probably already saw it is not referenced anywhere. They are just examples of how a plugin should be written and what it can do.

KostyaEsmukov commented 8 years ago

Dear Francesco, I think I understood everything correctly.

I understand that plugins are written by end users (developers). That's why I think that my first option (removing duplicated pairs of plugins) might be an appropriate solution here - they would still perfectly serve as examples, while honoring the DRY principle.

Of course I'm speaking here about those example plugins only. If we go with the first option, that doesn't mean that developers can't go with the second one for their own plugins.