Announcement

Collapse
No announcement yet.

Rewriting Hello World Revisited in node

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rewriting Hello World Revisited in node

    Hi,

    I am rewriting client from "hello world revisited" example to nodejs and have problems. Problems I'm having are with SignIn stored procedure, because I get multiple error messages:

    Code:
    VOLTDB ERROR: USER ABORT
      Expectation failing in procedure: SignIn
      Running SQL: SELECT H.HELLO, U.FIRSTNAME FROM USERACCOUNT AS U, HELLOWORLD AS H WHERE U.DIALECT = H.DIALECT AND U.EMAIL = ?;
      Error message: Expected one row, but got 0
        at SignIn.run(SignIn.java:16)
    When I run sqlcmd and observe select useraccount table, it looks like some signings were performed because "signin time" is not null.

    Here is the whole code:

    Code:
    var voltjs = require('voltjs'); //i tweaked a little voltjs package so it exports Volt* objects.
    
    var firstname    = ["Juan","John","Jean","Pierre","Peter","Pedro", "William","Willhem","Carlo", "Carlos","Carlita","Carmen"],
        helloworld   = [['Hello', 'World'], ['Bonjour', 'Monde'], ['Hola', 'Mundo'], ['Hej', 'Verden'], ['Ciao','Mondo']],
        lastname     = ["Brown","White","Black","Smith","Jones", "Green", "Calderon", "Tanaka","Lee","Lewis","Lincoln"],
        language     = ["English","French","Spanish","Danish","Italian"],
        emailservice = ["gmail","yahoo","msn","juno","aol"],
        servers      = ['localhost'],
        maxaccountID = 0;
    
    var registerUser = new voltjs.VoltProcedure('RegisterUser', ['string', 'string', 'string', 'string']),
        insert       = new voltjs.VoltProcedure('Insert', ['string', 'string', 'string']),
        signIn       = new voltjs.VoltProcedure('SignIn', ['string', 'long']);
    
    var configs = []
    for (var i=0; i<servers.length; i++) {
        var cfg = new voltjs.VoltConfiguration();
        cfg.host = servers[i];
        cfg.messageQueueSize = 10;
        configs.push(cfg);
    }
    
    client = new voltjs.VoltClient(configs);
    
    // client.on(voltjs.VoltConstants.SESSION_EVENT.CONNECTION, eventListener);
    // client.on(voltjs.VoltConstants.SESSION_EVENT.CONNECTION_ERROR, eventListener);
    // client.on(voltjs.VoltConstants.SESSION_EVENT.QUERY_RESPONSE_ERROR, eventListener);
    // client.on(voltjs.VoltConstants.SESSION_EVENT.QUERY_DISPATCH_ERROR, eventListener);
    // client.on(voltjs.VoltConstants.SESSION_EVENT.FATAL_ERROR, eventListener);
    
    client.connect(function(code, event, results) {
        console.log('Node connected to VoltDB');
        populateAndRegister();
        registerAndSignIn();
    }, function(code, event, results) {
        console.log('Node did not connect to VoltDB');
    });
    
    // insert helloworld records and make sure there are at least 5 useraccounts
    function populateAndRegister() {
        var query = insert.getQuery();
        for (var i=0; i<language.length; i++) {
            query.setParameters([language[i], helloworld[i][0], helloworld[i][1]]);
            client.callProcedure(query, callback);
        }
    
        var query = registerUser.getQuery();
        while (maxaccountID < 5) {
            query.setParameters([ generateEmail(maxaccountID), firstname[randomInt(10)], lastname[randomInt(10)], language[randomInt(5)] ]);
            client.callProcedure(query, callback);
            maxaccountID++;
        }
    }
    
    // for every 100 signings do 1 register
    // do this for 1 second
    function registerAndSignIn() {
        var countdownTimer = currentTimeMillis() + (1000);
    
        while(countdownTimer > currentTimeMillis()) {
    
            var query = signIn.getQuery();
            for(var i=0; i<100; i++) {
                var user = generateEmail(randomInt(maxaccountID));
                query.setParameters([user, currentTimeMillis()]);
                client.callProcedure(query, callback);
            }
    
            var query = registerUser.getQuery();
            query.setParameters([ generateEmail(randomInt(maxaccountID)), firstname[randomInt(10)], lastname[randomInt(10)], language[randomInt(5)] ]);
            client.callProcedure(query, callback);
    
            maxaccountID++;
        }
    }
    
    // call this when procedure is done
    function callback(code, event, results) {
        if (code == voltjs.VoltConstants.STATUS_CODES.SUCCESS) {
            console.log(results.statusString);
        } else {
            console.log('Couldn\'t execute procedure');
        }
    }
    
    function eventListener(code, event, message) {
        console.log('Event %s\tcode: %d\tMessage: %s', event, code, message);
    }
    function currentTimeMillis() {
        return process.hrtime()[0]*1000 + process.hrtime()[0]/1000000;
    }
    function generateEmail(id) {
        return id + "@" + emailservice[id % 5] + ".com";
    }
    
    function randomInt(high) {
        return Math.floor(Math.random() * high);
    }

  • #2
    Nevermind, I found the problem. As error implies, there is no user with that email in database. In signin process app is generating random emails but instead should be picking the ones already generated.

    I think VoltDB developers should correct the original "Hello World Revisited" client in java.

    Comment


    • #3
      Hi,

      Thanks for your posts. If you look at the documentation for Hello World Revisited in the Performance Guide it points out, as you discovered, that the stored procedure uses the expectation EXPECTS_ONE_ROW to verify that an existing account record was found. If you run the existing Java example you will see that it does not generate any errors. This is because although it randomly selects email addresses to use for signin, those email addresses are not actually random -- they all generate a deterministic email address based on an integer number:
      Code:
          static private String generateEmail(int id) {
              String address;
              int pseudorandom = id % 5;
              address = Integer.toString(id) + "@" + emailservice[pseudorandom] + ".com";
              return address;
          }
      In other words, given the same random number, it always generates the same email address.

      I am not familiar with node.js myself, so can't tell exactly where your code deviates from the example, but I suspect there may be an issue with scoping or JavaScript's less strict typing model may result in non deterministic emails being generated or random numbers outside the range of existing accounts. Is that possible?

      Comment

      Working...
      X