-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make providers WS and IPC reliable #5763
Conversation
Deploying with
|
Latest commit: |
b44fc31
|
Status: | ✅ Deploy successful! |
Preview URL: | https://ac1be8b6.web3-js-docs.pages.dev |
Branch Preview URL: | https://ok-5632-make-providers-ws-an.web3-js-docs.pages.dev |
@@ -22,7 +22,7 @@ | |||
"test:ci": "jest --coverage=true --coverage-reporters=json --verbose", | |||
"test:watch": "npm test -- --watch", | |||
"test:unit": "jest --config=./test/unit/jest.config.js", | |||
"test:integration": "jest --config=./test/integration/jest.config.js --passWithNoTests" | |||
"test:integration": "jest --config=./test/integration/jest.config.js --passWithNoTests --forceExit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is --forceExit
on for debugging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Locally it is not stuck, but in GitHub Action, sometimes yes. I need to investigate it deeply
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If its not fixed in current PR pls create issue pointing to this discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed the test. So it works without --forceExit
Looks good! 👍 |
public constructor(socketPath: string) { | ||
super(socketPath); | ||
|
||
public constructor(socketPath: string, options?: object, reconnectOptions?: object) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is doc updated for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipc provider doesn't have doc
}); | ||
} else { | ||
this._connectionStatus = 'disconnected'; | ||
throw new InvalidConnectionError(this._socketPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also include more error details coming via e
in } catch (e) {
to throw new InvalidConnectionError(this._socketPath)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
this._reconnectOptions.autoReconnect && | ||
(![1000, 1001].includes(event.code) || !event.wasClean) | ||
) { | ||
if (!event && this._reconnectOptions.autoReconnect) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be normal close events are those considered as well ?
so this condition should only be true if there is no clean close or event codes are not 1000 and 1001,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IPC providers use import { Socket } from 'net';
to connect.
in the close event of Socket we do not have any code
or wasClean
information.
That is why for IPC we have a different condition.
but when we call the disconnect
method we create an event on our own. and in this case, we will have an event object here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so is this tested for normal close, its existing without reconnect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this is a test "exit without reconnection":
it('should emit connect and disconnected events', async () => {
const server = await startGethServer(8547);
const web3Provider = new IpcProvider(server.path);
expect(!!(await waitForEvent(web3Provider, 'connect'))).toBe(true);
const disconnectPromise = waitForEvent(web3Provider, 'disconnect');
web3Provider.disconnect();
expect(!!(await disconnectPromise)).toBe(true);
await server.close();
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -76,13 +72,16 @@ export default class WebSocketProvider< | |||
|
|||
this._addSocketListeners(); | |||
} catch (e) { | |||
throw new InvalidConnectionError(this._socketPath); | |||
if (!this.isReconnecting) { | |||
throw new InvalidConnectionError(this._socketPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls also include more error details from e obj in rethrow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
LGTM, Some of WS tests are not invoked in CI, pls check before merging if there is any thing with current PR causing it. @avkos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
However, I have a few comments.
it('check defaults', async () => { | ||
const web3Provider = new WebSocketProvider(getSystemTestProvider()); | ||
// @ts-expect-error-next-line | ||
expect(web3Provider._reconnectOptions).toEqual({ | ||
autoReconnect: true, | ||
delay: 5000, | ||
maxAttempts: 5, | ||
}); | ||
await waitForOpenConnection(web3Provider); | ||
web3Provider.disconnect(1000, 'test'); | ||
await waitForCloseConnection(web3Provider); | ||
}); | ||
it('set custom reconnectOptions', async () => { | ||
const web3Provider = new WebSocketProvider( | ||
getSystemTestProvider(), | ||
{}, | ||
reconnectionOptions, | ||
); | ||
// @ts-expect-error-next-line | ||
expect(web3Provider._reconnectOptions).toEqual(reconnectionOptions); | ||
await waitForOpenConnection(web3Provider); | ||
web3Provider.disconnect(1000, 'test'); | ||
await waitForCloseConnection(web3Provider); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the logic of those 2 tests could be moved to web3-utils
. We just need to keep the Provider initialization. And the rest is douplicate with IpcProvider. Or what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can have tests here and in web3-utils just to be sure it works not only on base class but in WebsocketProvider and in IPCProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I meant to have only the provider initialization at this package:
const web3Provider = new WebSocketProvider(
getSystemTestProvider(),
{},
reconnectionOptions,
);
And then the object web3Provider
could be passed to a function that contains the logic (that is exactly the same for both WS and IPC):
// @ts-expect-error-next-line
expect(web3Provider._reconnectOptions).toEqual(reconnectionOptions);
await waitForOpenConnection(web3Provider);
web3Provider.disconnect(1000, 'test');
await waitForCloseConnection(web3Provider);
if [ -z "${ORIGARGS[1]}" ] | ||
then | ||
echo "Starting geth..." | ||
echo "docker run -p $WEB3_SYSTEM_TEST_PORT:$WEB3_SYSTEM_TEST_PORT --name web3-geth-client ethereum/client-go --nodiscover --nousb --ws --ws.addr 0.0.0.0 --ws.port $WEB3_SYSTEM_TEST_PORT --http --http.addr 0.0.0.0 --http.port $WEB3_SYSTEM_TEST_PORT --allow-insecure-unlock --http.api personal,web3,eth,admin,debug,txpool,net --ws.api personal,web3,eth,admin,debug,miner,txpool,net --dev" | ||
docker run -p $WEB3_SYSTEM_TEST_PORT:$WEB3_SYSTEM_TEST_PORT ethereum/client-go --nodiscover --nousb --ws --ws.addr 0.0.0.0 --ws.port $WEB3_SYSTEM_TEST_PORT --http --http.addr 0.0.0.0 --http.port $WEB3_SYSTEM_TEST_PORT --allow-insecure-unlock --http.api personal,web3,eth,admin,debug,txpool,net --ws.api personal,web3,eth,admin,debug,miner,txpool,net --dev | ||
echo "docker run -p $WEB3_SYSTEM_TEST_PORT:$WEB3_SYSTEM_TEST_PORT ethereum/client-go:stable --nodiscover --nousb --ws --ws.addr 0.0.0.0 --ws.port $WEB3_SYSTEM_TEST_PORT --http --http.addr 0.0.0.0 --http.port $WEB3_SYSTEM_TEST_PORT --allow-insecure-unlock --http.api personal,web3,eth,admin,debug,txpool,net --ws.api personal,web3,eth,admin,debug,miner,txpool,net --dev" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having a name for the docker container is something good. I mean to keep --name web3-geth-client
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make changes in docker in another PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for this I recommend not changing the docker configuration related to the docker image name (--name web3-geth-client
) in this MR 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work Oleksii,
I have just 2 minor comments that you may consider. And you may merge without considering them.
Description
fixes #5632
Please include a summary of the changes and be sure to follow our Contribution Guidelines.
Checklist for 4.x:
yarn
successfullyyarn lint
successfullyyarn build:web
successfullyyarn test:unit
successfullyyarn test:integration
successfullycompile:contracts
successfullyCHANGELOG.md
file in the packages I have edited.