I want to use Linux::Inotify2 to monitor the file attributes change in Mojolicious's Controller 。
I think the Linux::Inotify2 should use Mojolicious's Mojo::Loop, is this right ?
but the following code does not work . please help me , very thanks !
== code ==:101 # NOTE: use websocket 102 sub status{ 103 my $self = shift; 104 my $server = $self->stash('server'); 105 my $tag = $self->stash('tag'); 106 107 $self->server($server); 108 $self->tag($tag); 109 110 # identify an instance 111 my $file = $server ."-" . $tag; 112 113 state $ws_clients = {}; # file => [ws1,ws2...] 114 state $notifys = {} ;# file => notify_instance 115 116 $self->on(message => sub { 117 # nothing 118 my ($ws,$msg) = @_; 119 $self->app->log->debug('[Memoryanalyzer] status -> cli +ent msg:',$msg); 120 $self->app->log->debug('notify file number is : ',$not +ifys->{$file}->fileno); 121 $ws->send(Mojo::JSON->new->encode({ 122 status => 'success', 123 data => 'alive' 124 })); 125 }); 126 $self->on(finish => sub { 127 my $ws = shift; 128 $self->app->log->debug('[Memoryanalyzer] status -> fin +ish connection'); 129 # clean 130 @{$ws_clients->{$file}} = grep { $_ != $ws } @{$ws_cli +ents->{$file}}; 131 unless(@{$ws_clients->{$file}}){ 132 # no websocket connected 133 $ws_clients->{$file}=undef; 134 $notifys->{$file}=undef; 135 # Mojo::IOLoop->remove($s_id); 136 } 137 }); 138 # keep alive 20s 139 Mojo::IOLoop->stream($self->tx->connection)->timeout(20); 140 141 $self->app->log->debug('[Memoryanalyzer] status -> file:',$fil +e); 142 143 # remeber websocket connection to hash for notify later. 144 push @{$ws_clients->{$file}},$self; 145 146 # only create one inotifyer for one "file" 147 unless(@{$ws_clients->{$file}} >1){ 148 my $status_file = $self->status_file; 149 my ($stream,$notify,$notify_fh,$stream_id,$get_status); 150 151 $get_status = sub { 152 $self->app->log->debug('[Memoryanalyzer] get_status'); 153 my $s_fh; 154 # open status_file failed 155 my ($status,$data); 156 unless(open $s_fh,'<',$status_file){ 157 $status = "error"; 158 $data = "open status file failed"; 159 }else{ 160 local $/=undef; 161 my $content = <$s_fh>; 162 close($s_fh); 163 if($content =~ m/^==([a-za-z]+)(?:(.*?)|)==$/){ 164 $status = $1; 165 $data = $2; 166 }else{ 167 $status = "error"; 168 $data = "invalid status string:".$content; 169 } 170 171 } 172 173 foreach my $ws (@{$ws_clients->{$file}}){ 174 $ws->send(Mojo::JSON->new->encode({status => $stat +us, data => $data})); 175 } 176 177 # background command is finished 178 # destory notifyer and close websocket connection 179 # also remove stream object 180 if($status ne "running"){ 181 $self->app->log->debug('[Memoryanalyzer] status -> + status not running:',$status,$data); 182 foreach my $ws(@{$ws_clients->{$file}}){ 183 $ws->finish; 184 } 185 $ws_clients->{$file}=undef; 186 $notifys->{$file}=undef; 187 Mojo::IOLoop->remove($stream_id) if $stream_id; 188 return 1; 189 } 190 return 0; 191 }; 192 # at first, check the content of status-file , maybe it's +already finished; 193 return if &$get_status(); 194 195 $self->app->log->debug('[Memoryanalyzer] status -> create +notifyer'); 196 $notify = new Linux::Inotify2; 197 unless($notify){ 198 shift @{$ws_clients->{$file}}; 199 die "create Linux::Inotify2 instance failed"; 200 } 201 $notify->watch($status_file,IN_CLOSE_WRITE); 202 203 $notifys->{$file} = $notify; 204 205 unless(open $notify_fh, "<&=".$notify->fileno){ 206 shift @{$ws_clients->{$file}}; 207 die "can not covert fd to filehandler: fd = ".$notify- +>fileno; 208 } 209 210 $stream = Mojo::IOLoop::Stream->new($notify_fh); 211 $stream_id = Mojo::IOLoop->stream($stream); 212 $stream->on(read => $get_status); 213 $stream->start; 214 Mojo::IOLoop->start unless Mojo::IOLoop->is_running; 215 } 216 }
In reply to use Linux::Inotify2 in Mojolicious Controller by chinaxing
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |