openchain / openchain-js

JavaScript Openchain client library for Node.js and the browser
https://www.openchain.org/
Apache License 2.0
75 stars 39 forks source link

intialize function never resolves #1

Open petethomas opened 8 years ago

petethomas commented 8 years ago

We're running into an issue with the initialize function for the ApiClient never resolving or rejecting. It just hangs forever. When we connect to https://test.openchain.org with the client, it will initialize, but not when connecting to a local instance at http://localhost:8080. In this case we're running the Openchain docker image on OSX 10.10.5. Below is a test script that replicates our issue:

var openchain = require('openchain');
var client = new openchain.ApiClient('http://localhost:8080');
console.log('Initializing Openchain client');
client.initialize().then(function () {
    console.log('Openchain client initialized');
}, function (err) {
    console.error(err.stack);
});

When we run the script, 'Initializing Openchain client' is logged, and nothing else happens. The promise that is returned from getInfo() never resolves, though if we run curl http://localhost:8080/info in a terminal, we get a 200 and the JSON containing the namespace back.

We noticed that if we run docker-compose restart to restart the openchain-server container while that script is running, after a few seconds, the promise returned from initialize resolves.

Provided this is not a configuration issue on our side, could our issue have something to do with differences between httpinvoke in the browser and httpinvoke running in node, e.g. https://github.com/jakutis/httpinvoke/issues/17

Flavien commented 8 years ago

The current version of the Kestrel web server used by Openchain (RC1) has a bug whereby requests have to be made with keep alive on when called from Node.

This will be fixed as soon as RC2 is released, but in the meantime, there are a couple of solutions:

  1. Expose Openchain behind IIS or Nginx, which will handle the incoming calls correctly, or
  2. Override the httpGet and httpPost methods of the API client object:
var httpinvoke = require("httpinvoke");

client.httpGet = function (url) {
    return httpinvoke(url, "GET", { headers: { 'Connection': 'keep-alive' } })
    .then(function (data) {
        return JSON.parse(data.body);
    });
};

client.httpPost = function (url, body) {
    return httpinvoke(url, "POST", { headers: { 'Connection': 'keep-alive' }, input: body })
    .then(function (data) {
        return JSON.parse(data.body);
    });
};