@moneypot/hub 1.22.3 → 1.22.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { createClient as createWebsocketClient, } from "graphql-ws";
2
2
  import { gql } from "../__generated__/gql.js";
3
- import { print } from "graphql";
3
+ import { getOperationAST, print } from "graphql";
4
4
  import { createGraphqlClient } from "../graphql-client.js";
5
5
  import { useFragment } from "../__generated__/fragment-masking.js";
6
6
  import { TRANSFER_FIELDS } from "./graphql.js";
@@ -51,6 +51,8 @@ async function mpGetExperienceTransfer(graphqlClient, id) {
51
51
  return mpTransfer;
52
52
  }
53
53
  export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controllerId, apiKey, pool, }) {
54
+ if (signal.aborted)
55
+ return;
54
56
  logger.info(`Starting websocket processor for ${graphqlUrl}`);
55
57
  const client = createWebsocketClient({
56
58
  url: httpToWs(new URL(graphqlUrl)).toString(),
@@ -63,9 +65,7 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
63
65
  },
64
66
  keepAlive: 1_000,
65
67
  retryWait: async (retries) => {
66
- const baseDelay = Math.min(1000 * Math.pow(2, retries), 30_000);
67
- const jitter = Math.floor(Math.random() * 10_000);
68
- await abortableTimeout(baseDelay + jitter, signal);
68
+ await abortableTimeout(backoffDelayMs(retries), signal);
69
69
  },
70
70
  });
71
71
  client.on("connected", () => {
@@ -78,60 +78,83 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
78
78
  logger.error(error, `[websocketProcessor] Error on websocket ${graphqlUrl}`);
79
79
  });
80
80
  const graphqlClient = createGraphqlClient({ graphqlUrl, apiKey });
81
- const dispose1 = createSubscription(client, MP_NEW_EXPERIENCE_TRANSFER, async (result) => {
82
- const transferId = result.data?.newExperienceTransfer?.id;
83
- if (!transferId) {
84
- logger.warn(result, `Weird, no transfer id in websocket result`);
85
- return;
86
- }
87
- const mpTransfer = await mpGetExperienceTransfer(graphqlClient, transferId);
88
- if (!mpTransfer) {
89
- logger.warn(`No experience transfer found in casino api for mp transfer id ${transferId}`);
90
- return;
91
- }
92
- assert(mpTransfer.__typename === "ExperienceTransfer", `Expected experience transfer but got ${mpTransfer.__typename}`);
93
- await processTransfer({
94
- casinoId,
95
- controllerId,
96
- transfer: mpTransfer,
97
- graphqlClient,
98
- pool,
99
- });
100
- });
101
- const dispose2 = createSubscription(client, MP_NEW_TAKE_REQUEST, async (result) => {
102
- const mpTakeRequestId = result.data?.newTakeRequest?.id;
103
- if (!mpTakeRequestId) {
104
- logger.warn(result, `Weird, no take request id in websocket result`);
105
- return;
106
- }
107
- const mpTakeRequest = await mpGetTakeRequest(graphqlClient, mpTakeRequestId);
108
- if (!mpTakeRequest) {
109
- logger.warn(`No take request found in casino api for mp take request id ${mpTakeRequestId}`);
110
- return;
111
- }
112
- await processSingleTakeRequest({
113
- mpTakeRequestId,
114
- mpTakeRequest,
115
- casinoId,
116
- graphqlClient,
117
- pool,
118
- });
119
- });
120
- signal.addEventListener("abort", () => {
121
- dispose1();
122
- dispose2();
123
- });
124
- }
125
- function createSubscription(client, query, handler) {
126
- return client.subscribe({ query: print(query) }, {
127
- next: (result) => {
128
- handler(result).catch((e) => {
129
- logger.error(e, `Error while handling websocket result`);
81
+ keepSubscribed({
82
+ client,
83
+ query: MP_NEW_EXPERIENCE_TRANSFER,
84
+ signal,
85
+ idOf: (result) => result.data?.newExperienceTransfer?.id,
86
+ handleId: async (transferId) => {
87
+ const mpTransfer = await mpGetExperienceTransfer(graphqlClient, transferId);
88
+ if (!mpTransfer) {
89
+ logger.warn(`No experience transfer found in casino api for mp transfer id ${transferId}`);
90
+ return;
91
+ }
92
+ assert(mpTransfer.__typename === "ExperienceTransfer", `Expected experience transfer but got ${mpTransfer.__typename}`);
93
+ await processTransfer({
94
+ casinoId,
95
+ controllerId,
96
+ transfer: mpTransfer,
97
+ graphqlClient,
98
+ pool,
130
99
  });
131
100
  },
132
- error: (err) => {
133
- logger.error(err, `Error during WebSocket subscription`);
101
+ });
102
+ keepSubscribed({
103
+ client,
104
+ query: MP_NEW_TAKE_REQUEST,
105
+ signal,
106
+ idOf: (result) => result.data?.newTakeRequest?.id,
107
+ handleId: async (mpTakeRequestId) => {
108
+ const mpTakeRequest = await mpGetTakeRequest(graphqlClient, mpTakeRequestId);
109
+ if (!mpTakeRequest) {
110
+ logger.warn(`No take request found in casino api for mp take request id ${mpTakeRequestId}`);
111
+ return;
112
+ }
113
+ await processSingleTakeRequest({
114
+ mpTakeRequestId,
115
+ mpTakeRequest,
116
+ casinoId,
117
+ graphqlClient,
118
+ pool,
119
+ });
134
120
  },
135
- complete: () => logger.info("Subscription closed"),
136
121
  });
137
122
  }
123
+ function backoffDelayMs(attempt) {
124
+ const baseDelay = Math.min(1000 * Math.pow(2, attempt), 30_000);
125
+ const jitter = Math.floor(Math.random() * 10_000);
126
+ return baseDelay + jitter;
127
+ }
128
+ function keepSubscribed({ client, query, signal, idOf, handleId, }) {
129
+ const name = getOperationAST(query)?.name?.value ?? "subscription";
130
+ let attempt = 0;
131
+ let dispose = () => { };
132
+ const ended = (how, err) => {
133
+ if (signal.aborted)
134
+ return;
135
+ const delay = backoffDelayMs(attempt++);
136
+ logger.warn({ err }, `[websocketProcessor] Casino ended ${name} with ${how}, resubscribing in ${delay}ms`);
137
+ abortableTimeout(delay, signal).then(subscribe);
138
+ };
139
+ const subscribe = () => {
140
+ if (signal.aborted)
141
+ return;
142
+ dispose = client.subscribe({ query: print(query) }, {
143
+ next: (result) => {
144
+ const id = idOf(result);
145
+ if (!id) {
146
+ logger.warn(result, `Weird, no id in ${name} websocket result`);
147
+ return;
148
+ }
149
+ attempt = 0;
150
+ handleId(id).catch((e) => {
151
+ logger.error(e, `Error while handling websocket result`);
152
+ });
153
+ },
154
+ error: (err) => ended("error", err),
155
+ complete: () => ended("complete"),
156
+ });
157
+ };
158
+ signal.addEventListener("abort", () => dispose(), { once: true });
159
+ subscribe();
160
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.22.3",
3
+ "version": "1.22.4",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [