hoelz.ro - Using XMPP to Find Out When a Long-Running Process is Done

Using XMPP to Find Out When a Long-Running Process is Done

Do you often find yourself running a process that you know is going to take a while? Do you also find yourself checking the shell it's running in every five minutes to see if it's done? I do this fairly often, so what I used to do is something like this:

my-long-running-process; notify-send Complete "Your long-running process is complete"

This pops up a nice GUI notification letting me know my process is done. However, it has a few disadvantages. One is that it requires me to be at the machine I'm running the job on; sometimes I set up a job to run and leave. Another disadvantage is that I may miss the GUI notification if I get up from my desk to grab a cup of coffee or something.

I decided the best alternative would be to write a simple script that would notify me over XMPP that my job had completed. That way, my IM program would let me know I had a message when I got back to my laptop, and my phone would receive the message too. So now what I do is this:

my-long-running-process; notify-rob.pl "Your long-running process is complete"

That's nice, but if I'm running a process while I'm out and about and I'm interested in a summary of the data it outputs, I'd like that included in the message. So I added support for using standard input as the message. Let's say I want to know how long my process took:

(time my-long-running-process) 2>&1 | notify-rob.pl -i

Now when my-long-running-process completes, it sends a message with the duration of the job to my phone, as well as any chat clients I have running at the time.

Here's my notify-rob.pl script, with the Rob-specific bits removed. If you'd like to use it, you'll need the AnyEvent-XMPP distribution installed for Perl, and perl 5.10 or better.

notify-rob.pl
  1. #!/usr/bin/env perl
  2.  
  3. use strict;
  4. use warnings;
  5. use feature 'say';
  6.  
  7. use AnyEvent::XMPP::IM::Connection;
  8. use AnyEvent::XMPP::IM::Message;
  9. use Getopt::Long;
  10.  
  11. my $from_stdin = 0;
  12. my $from_file = 0;
  13.  
  14. GetOptions(
  15. input => \$from_stdin,
  16. 'file=s' => \$from_file,
  17. );
  18.  
  19. my $body;
  20.  
  21. if($from_stdin || $from_file) {
  22. my $fh;
  23.  
  24. if($from_stdin) {
  25. $fh = \*STDIN;
  26. } else {
  27. open $fh, '<', $from_file or die "Unable to open $from_file: $!\n";
  28. }
  29.  
  30. $body = do {
  31. local $/;
  32.  
  33. <$fh>;
  34. };
  35.  
  36. close $fh;
  37. } elsif(@ARGV) {
  38. $body = join(' ', @ARGV);
  39. } else {
  40. die "usage: $0 [-i] [-f file] [message...]\n";
  41. }
  42.  
  43. my $cond = AnyEvent->condvar;
  44. my $conn = AnyEvent::XMPP::IM::Connection->new(
  45. jid => 'your source JID here',
  46. password => 'your password here',
  47. domain => 'gmail.com', # I use Google Talk for this; you can
  48. # remove the domain, host, port, and
  49. # old_style_ssl options if you use
  50. # a "regular" XMPP server
  51. host => 'talk.google.com',
  52. port => 5223,
  53. old_style_ssl => 1,
  54. initial_presence => undef,
  55. );
  56.  
  57. my $timer;
  58. $conn->reg_cb(session_ready => sub {
  59. my $msg = AnyEvent::XMPP::IM::Message->new(
  60. to => 'your destination JID here',
  61. type => 'chat',
  62. body => $body,
  63. );
  64. $msg->send($conn);
  65. $timer = AnyEvent->timer(
  66. after => 3,
  67. cb => sub { $cond->send },
  68. );
  69. });
  70.  
  71. $conn->reg_cb(error => sub {
  72. my ( undef, $error ) = @_;
  73.  
  74. say $error->string;
  75. $cond->send;
  76. });
  77.  
  78. $conn->connect;
  79. $cond->recv;

Discussion

Enter your comment
If you can't read the letters on the image, download this .wav file to get them read to you.
 

Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki ipv6 ready