Vinicius Souza
Vinicius Souza

Reputation: 113

Intermittent error "This socket has been ended by the other party"

i'm connecting to my neo4j running on a docker container and i'm getting an error when i try to attempt to make another connection/query. The error is "This socket has been ended by the other party". This is my Dockerfile with the opened ports:

EXPOSE 7474 7473 7687

This is my driver utility:

var neo4j = require("neo4j-driver").v1,
    config = require("../../config");

(function(module){ 
    module.exports = function(){
        config.neo4j.server = 'localhost';
        return neo4j.driver("bolt://" + config.neo4j.server, neo4j.auth.basic(config.neo4j.user, config.neo4j.password));
    }
}(module));

The way i'm making my queries to neo4j:

(function(module){
    var driver = require('../../../utils/neo4j-driver')(),
        Q = require('q'),
        logger = require('../../../utils/logger'),
        BaseNeo4jModel = require('../../../utils/neo4j-model');

    function userDBAuth(user){
        var deferred = Q.defer();
        var session = driver.session();

        session
            //.run( "MATCH (a:Person) RETURN a.name AS name, a.uuid as uuid" )
            .run("MATCH (user:User {email:{email}})"
                    + "RETURN user",
                    { email: user.email})
            .then(function (result) {
                logger.debug('fetching results...');

                if(result.records.length > 0){
                    var records = [];

                    result.records.forEach(function(record){
                        records.push(new BaseNeo4jModel(record));
                    });

                    done();

                    deferred.resolve(records);
                } else {
                    deferred.reject({sucess: false, message: 'User not Found'});
                }

            }).catch( function(err) {
                logger.error(err);
                done();
                deferred.reject(err.fields[0]);
            });

            return deferred.promise;

        function done(){
            session.close();
            driver.close();
        }
    }

    module.exports = userDBAuth;

}(module));

And this is my stack trace:

{"name":"auth-services","hostname":"MacBook-Pro-de-Vinicius.local","pid":16292,"level":50,"err":{"message":"This socket has been ended by the other party","name":"Error","stack":"Error: This socket has been ended by the other party
at TLSSocket.writeAfterFIN [as write] (net.js:286:12)
at NodeChannel.write (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/ch-node.js:285:20)
at Chunker.flush (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/chunking.js:114:18)
at Connection.sync (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/internal/connector.js:487:21)
at Session.run (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/neo4j-driver/lib/v1/session.js:89:20)
at userDBAuth (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/services/userDBAuth.js:13:7)
at Object._auth [as auth] (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/services/auth.js:9:3)
at Server.auth (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/app/api/auth/resources/auth.js:7:12)
at next (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/restify/lib/server.js:906:30)
at f (/Users/viniciussouza/Sites/WeddSocial/backend/weddsocial-auth/node_modules/once/once.js:25:25)","code":"EPIPE"},"msg":"This socket has been ended by the other party","time":"2016-09-27T11:12:33.163Z","v":0}

I'm desperate, please help me!

Upvotes: 1

Views: 3460

Answers (2)

Peter Whitfield
Peter Whitfield

Reputation: 525

We were getting the same errors and traced it down to our code where we were sometimes committing our transaction before all the queries in the transaction were complete.

Having a look at your code, I'd suggest something like:

(function (module) {
    var driver = require('../../../utils/neo4j-driver')(),
        Q = require('q'),
        logger = require('../../../utils/logger'),
        BaseNeo4jModel = require('../../../utils/neo4j-model');

    function userDBAuth(user) {
        var session = driver.session();

        return session
            .run("MATCH (user:User {email:{email}}) RETURN user", {email: user.email})
            .then(function (result) {
                logger.debug('fetching results...');

                if (result.records.length === 0) {
                    return Q.reject({success: false, message: 'User not Found'}); // will be caught by the .catch() below
                }
                var records = result.records.map(function(record) {
                        return new BaseNeo4jModel(record); // assume this is synchronous and doesn't return a promise
                    });
                done();
                return records;
            })
            .catch(function (err) {
                logger.error(err);
                done();
                Q.reject(err.fields[0]); // return a rejected promise that can be caught by the caller of userDBAuth
            });

        function done() {
            session.close();
            driver.close();
        }
    }

    module.exports = userDBAuth;

}(module));

Not certain that this will solve your problem as you're not doing exactly what we are, just a suggestion based on what we found.

Upvotes: 0

Chris White
Chris White

Reputation: 30089

Just a suggestion - but it looks like your success path doesn't always call the done() method and hence the session isn't always closed out and returned to the pool.

Might i suggest you amend the following:

            if(result.records.length > 0){
                var records = [];

                result.records.forEach(function(record){
                    records.push(new BaseNeo4jModel(record));
                });

                done();

                deferred.resolve(records);
            } else {
                deferred.reject({sucess: false, message: 'User not Found'});
            }

To add a done() call in the else block:

            if(result.records.length > 0){
                var records = [];

                result.records.forEach(function(record){
                    records.push(new BaseNeo4jModel(record));
                });

                done();

                deferred.resolve(records);
            } else {
                done();
                deferred.reject({sucess: false, message: 'User not Found'});
            }

Upvotes: 1

Related Questions