Events not being responded to with namespace

Issue #57 invalid
Steve Fatula created an issue

I am on ubuntu 18.04.2, and, php 7.2.19. pecl event is installed, it’s 2.5.3. libevent is 2.1.6. I have the sample program attached that I was using to learn about event having never used it. I had to strip it down for this example, and, the echos are just there and I was spending so much time not having connections accepted, i.e. ,it never displayed “Accepting connection”.

So, php Test.php and the output is:

Address Port
About to do loop

Now, remove the namespace line, and, the output is:

Address Port

About to do loop

Accepting connection

What is the problem with namespaces here? We have an app that has a few hundred thousand lines and extensively uses namespaces, so, obviously, not going to remove them. Is there a syntax that would allow it to work with namespaces?

Comments (3)

  1. Steve Fatula reporter

    So, bad example from editing, let me retry. I’ll post the code below. Note the onRead never fires if you execute the code. However, remove the namespace line, and, remove all \Fatula\, and, it works. So, somehow namespaces work in the EventListener construct, however, do not work in EventBufferEvent.

    Unless I have missed something.

    <?php
    
    namespace Fatula;
    
    // Global variables
    $Connection = []; // List of connections
    
    function acceptConnection($Listener, $FileDescriptor, $IPaddress, $CustomArgs) {
        global $Connection;
    
        echo "Accepting connection\n";
        $Connection[$FileDescriptor] = new \EventBufferEvent($CustomArgs, $FileDescriptor, 0, "\Fatula\onRead", NULL, "\Fatula\onStatus");
        $Status = $Connection[$FileDescriptor]->enable(Event::READ | Event::WRITE);
        if ($Status === FALSE) echo "enable failed\n";
    }
    
    function acceptError(\EventListener $Listener, $CustomArgs) {
        echo "Got error " . \EventUtil::getLastSocketErrno() . ":". \EventUtil::getLastSocketError() . "\n";
    }
    
    function onRead(\EventBufferEvent $EventBufferEv, $FileDescriptor) {
        echo "In onread\n";
        $EventBuffer = $EventBufferEv->getInput();
        $Input = $EventBuffer->readLine(\EventBuffer::EOL_LF);
        echo "Data we got is " . $Input . "\n";
    }
    
    function onStatus(\EventBufferEvent $EventBufferEv, int $Events, $CustomArgs){
        if ($Events & \EventBufferEvent::READING) {
            echo "We are doing a READING event\n";
        }
        if ($Events & \EventBufferEvent::WRITING) {
            echo "We are doing a WRITING event\n";
        }
        if ($Events & \EventBufferEvent::EOF) {
            echo "We are doing a EOF event\n";
        }
        if ($Events & \EventBufferEvent::ERROR) {
            echo "We are doing a ERROR event\n";
        }
        if ($Events & \EventBufferEvent::TIMEOUT) {
            echo "We are doing a TIMEOUT event\n";
        }
    }
    
    $EventBase = new \EventBase();
    if ($EventBase === FALSE) {
        die("EventBase is false\n");
    }
    $ServerEventListener = new \EventListener($EventBase, "\Fatula\acceptConnection", $EventBase, \EventListener::OPT_CLOSE_ON_FREE | \EventListener::OPT_REUSEABLE, -1, "0.0.0.0:9901");
    if ($ServerEventListener === FALSE){
        die("ServerListener is false\n");
    }
    $Address = $Port = NULL;
    $OK = $ServerEventListener->getSocketName($Address, $Port);
    if ($OK === FALSE) echo "getSocketName failed\n";
    echo "Address {$Address} Port {$Port}\n";
    $ServerEventListener->setErrorCallback("\Fatula\acceptError");
    $ServerEventListener->enable();
    echo "About to do loop\n";
    $EventBase->dispatch();
    
    
    ?>
    
  2. Ruslan Osmanov repo owner

    The code refers to apparently non-existent Fatula\Event class:

    $Status = $Connection[$FileDescriptor]->enable(Event::READ | Event::WRITE);
    

    "Event" should have been prepended with a backslash. (The code generates an Error exception which is not bubbled up because of, well, another kind of issue.)


    Also, I’d like to point to the parts of the code that are on the verge of error:

    1. Don't enable events unless you handle them. In particular, Event::WRITE is enabled, but there is no matching callback set for it.
    2. Don’t use double-quoted string literals unless you really need PHP to interpret the special characters. E.g. "\Fatula\onStatus" is better written as '\Fatula\onStatus' or even __NAMESPACE__ . '\\onStatus'. In this particular case, you might save a closure into a variable and pass the variable instead of a string literal.
    3. I’d recommend following the PSR standards recommendations.
  3. Ruslan Osmanov repo owner

    Closing this issue, since the unexpected behavior was caused by a simple typo in the user's code.

  4. Log in to comment