PDA

View Full Version : Module "Reload" to ease development



vrobin
2008-11-09, 04:58
Hi,

A long time ago, I asked in the chat if there was a way to reload a module inside SqueezeCenter. At that time, for the people that were there, that wasn't easy with perl.

After more than a year of learning Perl, as I'm getting more experienced with, I find some ways to do this:
http://groups.google.com/group/comp.lang.perl/browse_thread/thread/cb59a6e9d53de1ca/3591ba3b10ac820f?lnk=gst&q=reload+module#3591ba3b10ac820f
http://search.cpan.org/author/JPRIT/Module-Reload-1.07/Reload.pm
http://search.cpan.org/author/CHTHORMAN/Module-Reload-Sel-1.02/Selective.pm

Wouldn't it be interesting to add a "reload plugin" command in the plugin settings? (I know, there can be some specific unregister/unload/load/register sequences to handle)

If not, how can I easily send a command (from the web interface, from the command line... maybe by adding an unused signal handler?) to a running instance of SqueezeCenter to force reload of a given module?

The problem is that it takes time to restart SqueezeCenter on the server (small C7 hardware) and a simple module reload would be much more efficient!

Robin

vrobin
2008-11-11, 03:40
Nobody has a reaction about this? Has this message been missed or is the focus on 7.3 release eating up all your time?

(I hope it worth trying a little "up" :) )

andyg
2008-11-11, 06:49
On Nov 11, 2008, at 5:40 AM, vrobin wrote:

>
> Nobody has a reaction about this? Has this message been missed or is
> the
> focus on 7.3 release eating up all your time?
>
> (I hope it worth trying a little "up" :) )

Feel free to play with this but dynamic module reloading is fraught
with all kinds of problems. It's usually best to just restart the
server.

vrobin
2008-11-11, 08:19
Thanks for the answer Andy. It doesn't sound like a good idea to include such functionality in SC core...

If I want to play with this only for me, what's the easiest way to trigger a method call inside squeezeserver from the outside world? (I think I'll give the sighandler method a try... I'm not sure it's very portable though)

Maybe registering a new method in the CLI could be another way of doing this... is this easy? (when I say easy, I mean one or two lines to register the method)

bpa
2008-11-11, 08:59
or register a http page handler - it's also an easy way to get some info from a plugin.
Slim::Web::HTTP::addPageFunction('plugins/myplugin/mypage.html', \&MyPageHandlerRoutine);

peterw
2008-11-11, 10:16
or register a http page handler - it's also an easy way to get some info from a plugin.
Slim::Web::HTTP::addPageFunction('plugins/myplugin/mypage.html', \&MyPageHandlerRoutine);

Take a look at the Slim:: classes -- generally if your web page does something interesting, as Robin's module reload would, you want to use Slim::Web::HTTP::protectURI to protect against CSRF attacks -- so you won't have to worry about possibly opening some web site with <IMG SRC="http://localhost:9000/plugins/myplugin/mypage.html" STYLE="visibility: hidden;" />. Registering the web handler, IIRC, should look more like


Slim::Web::HTTP::addPageFunction(Slim::Web::HTTP:: protectURI('plugins/myplugin/mypage.html'), \&MyPageHandlerRoutine);


But then you need to implement the handler... Registering a CLI command is easy, something like:



# register the command
Slim::Control::Request::addDispatch(['reloadmodules'], [0, 0, 0, \&myCLI]);
# protect from CSRF like /status.html?p0=reloadmodules
Slim::Web::HTTP::protectCommand('reloadmodules');

sub myCLI {
my $request = shift;
# much of this from IR Blaster
# Check this is the correct query
if( $request->isNotCommand( [['reloadmodules']] ) ) {
$request->setStatusBadDispatch();
return;
}
# do your work here
}


Oh, and as you might guess from the comments, any CLI command you register can be accessed with a URL: /status.html?p0=MYCOMMAND

Robin, I didn't comment b/c I've come to accept the startup speed on my dev box. Dynamic reload would be great, but if it adds any complexity to debugging & development, I'd rather keep starting new processes. Slow and simple beats fast and tricky in my book.

vrobin
2008-11-11, 10:42
Thanks both of you for the hints and code samples.

As I have nearly no knowledge of SC classes, these two ideas are interesting. I think I'll give the CLI example a try. The possibility to call the CLI command from an url makes this easy to access too.

I'll create a new generic "Reload module plugin" (I think putting the "reload" function in the plugin that you want to reload... isn't a good idea :) )

For sure some quick but tricky piece of code wouldn't help much if it's too tricky, but I'll try to do something simple. The only requirements for a plugin to support "reloading" would be the optional adding of an "unload" static method to unregister hooks before it is really reloaded.
The problem I want to address is both startup speed and continuous playing (I never took the time to build a dev instance of SC so when I tweak plugins, music stops playing... and I hate this! :) ).

I have some other work ongoing, but I'll keep you informed of my progress on the subject.

Triode
2008-11-11, 14:05
>
> Thanks both of you for the hints and code samples.
>
> As I have nearly no knowledge of SC classes, these two ideas are
> interesting. I think I'll give the CLI example a try. The possibility
> to call the CLI command from an url makes this easy to access too.
>
> I'll create a new generic "Reload module plugin" (I think putting the
> "reload" function in the plugin that you want to reload... isn't a good
> idea :) )
>
> For sure some quick but tricky piece of code wouldn't help much if it's
> too tricky, but I'll try to do something simple. The only requirements
> for a plugin to support "reloading" would be the optional adding of an
> "unload" static method to unregister hooks before it is really
> reloaded.
> The problem I want to address is both startup speed and continuous
> playing (I never took the time to build a dev instance of SC so when I
> tweak plugins, music stops playing... and I hate this! :) ).
>

For plugin installation/removal I think its safest to restart the server.
We used to have a mechanism to dynamically load a plugin, but the issue is
that its very difficult to ensure that all cases are trapped. There's also
far more permutations of plugin state if you allow this over forcing a
restart so it become more complex to test and maintain.

I would prefer we put effort into per platform mechanisms for restarting the
server. This way we will know that the server is in a known state when a
new plugin is loaded.

kdf
2008-11-11, 15:07
On 11-Nov-08, at 1:05 PM, Triode wrote:

>>
>
> For plugin installation/removal I think its safest to restart the
> server.

totally in agreement there.
>
> We used to have a mechanism to dynamically load a plugin, but the
> issue is
> that its very difficult to ensure that all cases are trapped.

It was terrible. Everything a plugin could do had to then be undone
in order to reload the configuration or disable.
Every time a plugin came up with something new that could be done, it
meant more rework to undo it. it was not always possible to even
clean it up correctly.
Especially now with far more powerful plugins, the only way to cleanly
change states is a server restart.

Granted, I haven't taken a look at the modules in question but I just
can't imaging they can completely get around that lack of garbage
collection in perl and SC would still have to undo SC alterations.

-kdf

vrobin
2008-11-12, 07:52
When starting this thread, I didn't expect such "no, don't even think about it; it's evil!" responses . Your experience with perl and SC being much more important than mine, I can't argue :).

These two last messages answer my first question ("would it be a good idea to create such a global behavior in SqueezeCenter code"). Obviously, it isn't!

Nevertheless, I still keep in mind the idea of a little piece of code that would reload .pm files inside a running SC. I have no experience with complex plugins that registers web interface, cli command (plugins that goes deep inside SC roots), but I think that this can still be useful for specific parts.
I don't mean to use it for whole plugin creation of course from the beginning to the end, but for small adjustments. This ".pm reload" could be used for small changes, restarting the whole server could then occur only once every ten module reloading.

This point of view is maybe the consequence of the way I'm writing perl code (run a test every two written lines :) ). I think I can unregister hooks, reload module and run "init" again, but I'm don't know what perl garbage does with anonymous data previously returned by the plugin and kept deep inside SC... sounds fun though! ;)