Skip to content

Commit 749035b

Browse files
committed
feat: free resources for garbage collection
1 parent 83111a1 commit 749035b

File tree

4 files changed

+40
-25
lines changed

4 files changed

+40
-25
lines changed

v-next/hardhat-errors/src/descriptors.ts

+7
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,13 @@ Try using another mnemonic or deriving less keys.`,
692692
websiteDescription:
693693
"The transaction to the null address cannot have undefined data",
694694
},
695+
PROVIDER_CLOSED: {
696+
number: 722,
697+
messageTemplate: "The provider has been closed.",
698+
websiteTitle: "Provider closed",
699+
websiteDescription:
700+
"The provider your are trying to use has been closed. Please create a new one using hre.network.connect() and try again.",
701+
},
695702
},
696703
KEYSTORE: {
697704
INVALID_KEYSTORE_FILE_FORMAT: {

v-next/hardhat/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import {
2222
l1GenesisState,
2323
l1HardforkFromString,
2424
} from "@ignored/edr-optimism";
25-
import { assertHardhatInvariant } from "@ignored/hardhat-vnext-errors";
25+
import {
26+
assertHardhatInvariant,
27+
HardhatError,
28+
} from "@ignored/hardhat-vnext-errors";
2629
import { toSeconds } from "@ignored/hardhat-vnext-utils/date";
2730
import { numberToHexString } from "@ignored/hardhat-vnext-utils/hex";
2831
import { deepEqual } from "@ignored/hardhat-vnext-utils/lang";
@@ -109,9 +112,9 @@ interface EdrProviderConfig {
109112
}
110113

111114
export class EdrProvider extends BaseProvider {
112-
readonly #provider: Readonly<Provider>;
113115
readonly #jsonRpcRequestWrapper?: JsonRpcRequestWrapperFunction;
114116

117+
#provider: Provider | undefined;
115118
#nextRequestId = 1;
116119

117120
/**
@@ -176,6 +179,10 @@ export class EdrProvider extends BaseProvider {
176179
public async request(
177180
requestArguments: RequestArguments,
178181
): Promise<SuccessfulJsonRpcResponse["result"]> {
182+
if (this.#provider === undefined) {
183+
throw new HardhatError(HardhatError.ERRORS.NETWORK.PROVIDER_CLOSED);
184+
}
185+
179186
const { method, params } = requestArguments;
180187

181188
const jsonRpcRequest = getJsonRpcRequest(
@@ -190,6 +197,11 @@ export class EdrProvider extends BaseProvider {
190197
jsonRpcResponse = await this.#jsonRpcRequestWrapper(
191198
jsonRpcRequest,
192199
async (request) => {
200+
assertHardhatInvariant(
201+
this.#provider !== undefined,
202+
"The provider is not defined",
203+
);
204+
193205
const stringifiedArgs = JSON.stringify(request);
194206
const edrResponse =
195207
await this.#provider.handleRequest(stringifiedArgs);
@@ -244,7 +256,8 @@ export class EdrProvider extends BaseProvider {
244256
}
245257

246258
public async close(): Promise<void> {
247-
// TODO: what needs cleaned up?
259+
// Clear the provider reference to help with garbage collection
260+
this.#provider = undefined;
248261
}
249262

250263
async #handleEdrResponse(

v-next/hardhat/src/internal/builtin-plugins/network-manager/http-provider.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ export class HttpProvider extends BaseProvider {
5050
readonly #url: string;
5151
readonly #networkName: string;
5252
readonly #extraHeaders: Readonly<Record<string, string>>;
53-
readonly #dispatcher: Readonly<Dispatcher>;
5453
readonly #jsonRpcRequestWrapper?: JsonRpcRequestWrapperFunction;
5554

55+
#dispatcher: Dispatcher | undefined;
5656
#nextRequestId = 1;
5757

5858
/**
@@ -112,6 +112,10 @@ export class HttpProvider extends BaseProvider {
112112
public async request(
113113
requestArguments: RequestArguments,
114114
): Promise<SuccessfulJsonRpcResponse["result"]> {
115+
if (this.#dispatcher === undefined) {
116+
throw new HardhatError(HardhatError.ERRORS.NETWORK.PROVIDER_CLOSED);
117+
}
118+
115119
const { method, params } = requestArguments;
116120

117121
const jsonRpcRequest = getJsonRpcRequest(
@@ -150,8 +154,11 @@ export class HttpProvider extends BaseProvider {
150154
}
151155

152156
public async close(): Promise<void> {
153-
// See https://github.com/nodejs/undici/discussions/3522#discussioncomment-10498734
154-
await this.#dispatcher.close();
157+
if (this.#dispatcher !== undefined) {
158+
// See https://github.com/nodejs/undici/discussions/3522#discussioncomment-10498734
159+
await this.#dispatcher.close();
160+
this.#dispatcher = undefined;
161+
}
155162
}
156163

157164
async #fetchJsonRpcResponse(

v-next/hardhat/test/internal/builtin-plugins/network-manager/http-provider.ts

+7-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import assert from "node:assert/strict";
44
import { describe, it } from "node:test";
55

66
import { HardhatError } from "@ignored/hardhat-vnext-errors";
7-
import { ensureError } from "@ignored/hardhat-vnext-utils/error";
87
import { numberToHexString } from "@ignored/hardhat-vnext-utils/hex";
98
import { assertRejectsWithHardhatError } from "@nomicfoundation/hardhat-test-utils";
109

@@ -498,25 +497,14 @@ describe("http-provider", () => {
498497
});
499498

500499
await provider.close();
501-
try {
502-
await provider.request({
503-
method: "eth_chainId",
504-
});
505-
} catch (error) {
506-
ensureError(error);
507500

508-
assert.ok(
509-
error.cause !== undefined && error.cause instanceof Error,
510-
"Error does not have a cause",
511-
);
512-
513-
// If the client is still open, the error will be a connection error
514-
if (error.cause.message === "getaddrinfo ENOTFOUND loocalhost") {
515-
assert.fail("Client is still open");
516-
}
517-
518-
assert.equal(error.cause.message, "The client is destroyed");
519-
}
501+
await assertRejectsWithHardhatError(
502+
provider.request({
503+
method: "eth_chainId",
504+
}),
505+
HardhatError.ERRORS.NETWORK.PROVIDER_CLOSED,
506+
{},
507+
);
520508
});
521509
});
522510
});

0 commit comments

Comments
 (0)