Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Unhandled Promise Rejection Warning #26

Closed
JoaoFSCruz opened this issue Mar 30, 2020 · 15 comments
Closed

Unhandled Promise Rejection Warning #26

JoaoFSCruz opened this issue Mar 30, 2020 · 15 comments

Comments

@JoaoFSCruz
Copy link

I'm currently participating in a European project called EUNOMIA where we need to decentralised the information. We rely on decoupled services and therefore have a main server responsible for managing data by using OrbitDB HTTP API (developed in Spring).

To assess the robustness of our server we made a load test by sending a lot of requests. During the test, our instance of OrbitDB HTTP Client threw some errors (a lot of these):

image

And after a while, our server was always receiving an error which implies the instance of OrbitDB HTTP API closed the connection without a response.

Server Error:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://orbitdb:3000/db/zdpuAnPwqKYn7gikwj4w2hDXKnJHFNJKkzwNLyL1qsrg9gZ8j%2Fmodel/put": Unexpected end of file from server; nested exception is java.net.SocketException: Unexpected end of file from server

I've tried different versions of OrbitDB, as another issue suggested, but without any luck.

Anyone has any idea of how to fix this problem? Many thanks 🙏

@aphelionz
Copy link
Contributor

This would happen when multiple processes are trying to open the same keystore - which would make sense during a load test... I'm wondering if this is Orbit, or if it's how the http-api is marshalling requests 🤔

What do you think, @phillmac ?

@phillmac
Copy link
Contributor

phillmac commented Mar 30, 2020

The http-api server spawns a single instance of orbitdb and tries very hard to only ever have a single instance of any given db open. Unless there is a logic flaw somewhere.
If there's two http-api processes running this could easily cause that error.
@aphelionz the put handler looks something like this:

handler: dbMiddleware( async (db, request, _h) => {
                    let params;
                    params = request.payload;

                    if (db.type == 'keyvalue') {
                        let key, value;
                        if (!params['key']) {
                            [key,value] = [Object.keys(params)[0], Object.values(params)[0]];
                        } else {
                            ({key,value} = params);
                        }
                        return {hash: await db.put(key, value)};
                    } else {
                        return {hash: await db.put(params)};
                    }
                }

So there's really no internal marshaling at all. The hapi server will process requests as fast as it can possibly pass them off to orbitdb.

Do we have a release that includes that PR for an internal operations marshaling queue?

@aphelionz
Copy link
Contributor

yeah that looks like it should work to me! @JoaoFSCruz do you have your load balancing code handy?

@phillmac
Copy link
Contributor

Perhaps this might be fixed by orbitdb-archive/orbit-db-store#85. I might try merging that PR in the development fork, and see if it fixes anything.

@phillmac
Copy link
Contributor

Another fix might be to use an external cache, e.g. redis. Is this a viable solution for you?

@JoaoFSCruz
Copy link
Author

Wow, thanks a lot for the fast responses!

@aphelionz We don't have load balancing code in our server, and I'm not sure if we are adding it. Either way, I'll suggest doing so. Thanks!

@phillmac I'll keep an eye out for the merge to test as soon as this possible fix is added.

@phillmac I'm not getting how that could help. In query requests yeah it does help a lot (and I'll suggest to implement it, thank you!), but in creating objects as I specified above there's not much it can do to help.

@phillmac
Copy link
Contributor

I was thinking using a cache like redis that can handle concurrent writes might fix your problem in the short term

@aphelionz
Copy link
Contributor

@phillmac any luck with that orbit-db-store PR?

@JoaoFSCruz
Copy link
Author

I'll be doing some more tests, and as soon as I have some results I'll post here.

@phillmac
Copy link
Contributor

phillmac commented Apr 1, 2020

@JoaoFSCruz I noticed you were using docker, phillmac/orbit-db-http-api-dev:debug is the bleeding edge build, warts and all. I've included orbitdb-archive/orbit-db-store#85 in the latest build, you may like to test if it fixes this issue or not. I haven't been able to replicate the problem yet, so I can't say for sure.

@JoaoFSCruz
Copy link
Author

Yeah, I'm using docker but not the official image. I pulled your image and made some adjustments in the query feature (which I'll use to create a PR someday, hopefully soon 🤞) and disabling HTTPS.

What do I need to run docker-compose with that image?

Right now I have this (which was working with our custom image):

  orbitdb:
    container_name: orbitdb
    image: phillmac/orbit-db-http-api-dev:debug
    depends_on: 
      - ipfs
      - ipfs-cluster
    ports: 
      - "3000:3000"
    volumes:
      - ./orbitdb

The tests I conducted with or custom image went rather well. Only some requests threw an error indicating it closed the connection without a response.

We used jmeter, here goes the test plan used including the results: load-test.zip.

@JoaoFSCruz
Copy link
Author

@phillmac couldn't use your image, always getting an error 🤷‍♂️ (error code 0) it just exited and didn't know where to get logs. But no worries!

I went to you repo and cloned it, changed to debug branch and altered your Dockerfile. I did the same load test (and heavier) and it worked like a charm! 🎉

I took a look inside the repo and saw it had a lot more functionalities. How stable is this version?

@phillmac
Copy link
Contributor

phillmac commented Apr 4, 2020

@JoaoFSCruz https://github.com/phillmac/orbit-db-http-api-dev is very much less stable than this repo. It's bleeding edge, proof-of-concept etc. and often gets broken. The problem is that I've let these two repos drift much too far apart to be able to merge new features.

here's an example docker-compose.yml

version: "3.7"

services:
  ipfs:
    image: ipfs/go-ipfs:v0.4.22
    restart: unless-stopped
    command: ["daemon", "--migrate=true", "--enable-gc", "--enable-namesys-pubsub"]
    volumes:
      - /ipfs_data:/data/ipfs
    ports:
      - 0.0.0.0:4001:4001/tcp
    networks:
      - ipfs
  orbitdb-api:
    image:  phillmac/orbit-db-http-api-dev:debug
    restart: unless-stopped
    command: ["src/cli.js", "api", "--debug"]
    init: TRUE
    environment:
      IPFS_HOST: 'ipfs'
      ORBITDB_DIR: '/orbitdb'
      FORCE_HTTP1: 'true'
      ANNOUNCE_DBS: 'true'
      LOG: 'DEBUG'
    depends_on:
      - ipfs
    ports:
      - 0.0.0.0:3000:3000/tcp
    networks:
      - ipfs
    volumes:
      - orbitdb-data:/orbitdb
networks:
  ipfs:
volumes:
  orbitdb-data:

a second example with letsencrypt certs :

 orbitdb-api:
    image:  phillmac/orbit-db-http-api-dev:debug
    restart: unless-stopped
    command: ["src/cli.js", "api", "--debug"]
    init: TRUE
    environment:
      IPFS_HOST: 'ipfs'
      ORBITDB_DIR: '/orbitdb'
      HTTPS_CERT: '/certs/live/xxxx.xxxx.xxxx/fullchain.pem'
      HTTPS_KEY: '/certs/live/xxxx.xxxx.xxxx/privkey.pem'
      ALLOW_HTTP1: 'true'
      ANNOUNCE_DBS: 'true'
      DEBUG_QUERY: 'true'
      LOG: DEBUG

    depends_on:
      - ipfs
    ports:
      - 0.0.0.0:3000:3000/tcp
    networks:
      - ipfs
    volumes:
      - type: volume
        source: orbitdb-data
        target: /orbitdb
      - type: volume
        source: cert-data
        target: /certs
        read_only: true
 

note:
FORCE_HTTP1: 'true' without ssl,
ALLOW_HTTP1: 'true' with ssl

@JoaoFSCruz
Copy link
Author

Thank you @phillmac! Worked perfectly!

@aphelionz
Copy link
Contributor

Closing this for now, good work gents!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants