Autoreload.pm 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package Trog::Autoreload;
  2. use strict;
  3. use warnings;
  4. no warnings qw{experimental};
  5. use feature qw{signatures};
  6. use Cwd qw{abs_path};
  7. use Time::HiRes qw{usleep};
  8. use Linux::Perl::inotify;
  9. use Trog::Utils;
  10. sub watch_for_changes ( $dir, $pid=undef ) {
  11. my @dirs = (abs_path($dir));
  12. my @wds;
  13. my $inf = Linux::Perl::inotify->new(flags => [qw{NONBLOCK}]);
  14. foreach my $directory (@dirs) {
  15. # Recursive scan for directories and setting up inotifies
  16. push(@dirs, _readdir( $directory ));
  17. print "Watching $directory for changes\n";
  18. push(@wds, $inf->add( path => $directory, events => [qw{CREATE MODIFY}] ));
  19. }
  20. my @result;
  21. CHECK: while (1) {
  22. @result = $inf->read();
  23. foreach my $res (@result) {
  24. last CHECK if $res->{name} =~ m/\.pm$/;
  25. }
  26. usleep 100000; #100ms oughtta be enough
  27. # If we know the pid, stop watching when it dies.
  28. if ($pid && !-d "/proc/$pid") {
  29. foreach my $wd (@wds) { $inf->remove($wd) }
  30. return 1;
  31. }
  32. }
  33. print "Relevant Change in $dir detected, reloading\n";
  34. Trog::Utils::restart_parent($pid);
  35. foreach my $wd (@wds) { $inf->remove($wd) }
  36. return 0;
  37. }
  38. sub _readdir ( $dir ) {
  39. opendir(my $dh, $dir);
  40. my @dirs = map { "$dir/$_" } grep { -d "$dir/$_" && !m/^\.+$/ } readdir($dh);
  41. closedir($dh);
  42. return @dirs;
  43. }
  44. sub monitor_pid {
  45. my $pf = 'run/monitor.pid';
  46. if (-f $pf) {
  47. open(my $pidfile, '<', $pf);
  48. read($pidfile, my $pid, 10000);
  49. close $pidfile;
  50. return $pid if -d "/proc/$pid";
  51. }
  52. return 0;
  53. }
  54. 1;