Algorithm-EventsPerSecond

 view release on metacpan or  search on metacpan

lib/Algorithm/EventsPerSecond/Sukkal.pm  view on Meta::CPAN

		my ( $r, $w ) = IO::Select->select( $rsel, $wsel, undef, $timeout );

		for my $fh ( @{ $r || [] } ) {
			if ( fileno($fh) == $self->{listener_fd} ) {
				$self->_accept;
			} else {
				$self->_read_client($fh);
			}
		}

		for my $fh ( @{ $w || [] } ) {
			# a connection dropped during the read pass may still be in
			# this list; its handle is closed, so fileno is undef
			my $id = fileno $fh;
			next unless defined $id && $self->{conns}{$id};
			$self->_flush( $self->{conns}{$id} );
		}

		if ( time() >= $self->{next_sweep} ) {
			$self->_sweep;
			$self->{next_sweep} = time() + $self->{sweep_interval};
		}
	} ## end while ( $self->{running} )

	$self->_shutdown;
	return $self;
} ## end sub run

=head2 stop

Ask a running daemon to shut down. Safe to call from a signal handler;
the L</run> loop notices on its next wakeup. Returns the daemon
object.

=cut

sub stop {
	my ($self) = @_;
	$self->{running} = 0;
	return $self;
}

sub _listen {
	my ($self) = @_;
	my $path = $self->{socket};

	if ( -e $path ) {
		die "$path exists and is not a socket\n" unless -S _;
		my $probe = IO::Socket::UNIX->new( Type => SOCK_STREAM, Peer => $path );
		die "something is already listening on $path\n" if $probe;
		unlink $path or die "cannot remove stale socket $path: $!\n";
	}

	my $listener = IO::Socket::UNIX->new(
		Type   => SOCK_STREAM,
		Local  => $path,
		Listen => $self->{listen_backlog},
	) or die "cannot listen on $path: $!\n";
	$listener->blocking(0);

	chmod $self->{socket_mode}, $path if defined $self->{socket_mode};

	$self->{listener}    = $listener;
	$self->{listener_fd} = fileno $listener;
	return;
} ## end sub _listen

sub _accept {
	my ($self) = @_;

	while ( my $fh = $self->{listener}->accept ) {
		if ( $self->{max_clients}
			&& keys %{ $self->{conns} } >= $self->{max_clients} )
		{
			close $fh;
			next;
		}
		$fh->blocking(0);
		my $id = fileno $fh;
		$self->{conns}{$id} = {
			fh      => $fh,
			id      => $id,
			rbuf    => '',
			wbuf    => '',
			closing => 0,
		};
		$self->{rsel}->add($fh);
	} ## end while ( my $fh = $self->{listener}->accept )
	return;
} ## end sub _accept

sub _read_client {
	my ( $self, $fh ) = @_;
	my $id = fileno $fh;
	my $c  = $self->{conns}{$id} or return;

	my $eof;
	# bounded so one firehose client cannot starve the rest of the loop
	for ( 1 .. 16 ) {
		my $n = sysread $fh, my $chunk, _READ_CHUNK;
		if ( !defined $n ) {
			last if $!{EAGAIN} || $!{EWOULDBLOCK} || $!{EINTR};
			$eof = 1;
			last;
		}
		if ( $n == 0 ) { $eof = 1; last }
		$c->{rbuf} .= $chunk;
		last if $n < _READ_CHUNK;
	} ## end for ( 1 .. 16 )

	if ( length $c->{rbuf} > _RBUF_MAX ) {
		$self->_send( $c, "ERR line too long\n" );
		return $self->_drop($c);
	}

	$self->_process($c);
	$self->_drop($c) if $eof && $self->{conns}{$id};
	return;
} ## end sub _read_client

sub _process {



( run in 1.079 second using v1.01-cache-2.11-cpan-6aa56a78535 )