kilgarenone / serverless-microservices

Serverless microservices. API gateway websocket. Dynamodb Streams
https://hungry-kalam-e19a74.netlify.app
2 stars 0 forks source link

Timeout? #2

Open msimonc opened 4 years ago

msimonc commented 4 years ago

Thanks for this project,

2 x browsers -> http://localhost:8009/

works great but then after several minutes new orders no longer get pushed to the second browser?

kilgarenone commented 4 years ago

You are welcome @msimonc .

I just checked, and seemed to be working fine- I open two browsers, create orders in either of them, and the orders are always synced on both sides.

When I saw your issue, I had already removed my serverless resources days ago. So to check for you, these are the things I did:

  1. cd orders-service. Then serverless deploy. Then copy and replace the given serverless endpoint in orders-app/.env.development file to the ORDERS_ENDPOINT variable.
  2. cd payments-service. Then serverless deploy. That's all for this.
  3. cd websocket-service. Then serverless deploy. Then, same drill: Copy and replace the given serverless endpoint in orders-app/.env.development file to the SERVERLESS_WEBSOCKET_ENDPOINT variable.
  4. Finally, at project's root, npm run dev. Open 2 browsers at localhost:8009, and try create orders on either side.

Hope that works!

msimonc commented 4 years ago

Hi @kilgarenone Thanks for the message. I only see the problem after waiting several minutes. How long did you wait ex. 15 mins,?

Also I logged the ws server on AWS, there was no $disconnect event.

Maybe the Lambda is going to sleep.

kilgarenone commented 4 years ago

oh I didn't wait that long. Ok so create an order and wait 15min and try again? Ok let me try.

hmm last I heard Lambda won't go to sleep anymore? but serverless is not my strongest suit...

will report back. cheers.

kilgarenone commented 4 years ago

@msimonc I just pinpoint the root cause!

So looks like it's a thing that the WebSocket at client-side would auto timeout...

I reckon this is how you could fix it- Refactor the orders-app/src/App.js like so:

  async componentDidMount() {
    this.setupWebSocket();

    const orders = await fetch(process.env.ORDERS_ENDPOINT).then((res) =>
      res.json()
    );

    this.setState({ orders });
  }

  setupWebSocket = () => {
    this.websocket = new WebSocket(process.env.SERVERLESS_WEBSOCKET_ENDPOINT);
    this.websocket.onopen = () => {
      console.log("hello client socket");
    };
    this.websocket.onclose = () => {
      console.log("bye bye client socket");
      setTimeout(this.setupWebSocket, 1000);
    };

    this.websocket.onmessage = ({ data }) => {
      const order = normalizeOrderObject(data);

      const { orderId, status } = order;

      if (!orderId) return;

      this.setState((prevState) => {
        const orders = [...prevState.orders];

        const orderIndex = orders.findIndex((o) => o.orderId === orderId);

        if (orderIndex < 0) {
          return { orders: [order].concat(prevState.orders) };
        }

        orders[orderIndex].status = status;
        return { orders };
      });
    };
  };

The ticket was this bit:

    this.websocket.onclose = () => {
       console.log("bye bye client socket");
       setTimeout(this.setupWebSocket, 1000); // re-init websocket when it tries to close
    };

I didn't test myself. Hope that works!

source: https://stackoverflow.com/a/28932266/73323