Skip to content
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

Remove ThreadPool.Serialize #2727

Closed

Conversation

bernardnormier
Copy link
Member

This PR removes thread pool serialization in all language mappings (C++, C#, Java).

@@ -614,8 +605,7 @@ IceInternal::ThreadPool::run(const EventHandlerThreadPtr& thread)
//
// Get the next ready handler.
//
while (_nextHandler != _handlers.end() &&
!(_nextHandler->second & ~_nextHandler->first->_disabled & _nextHandler->first->_registered))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find all these bitmask computations hard to read.

Now that _disabled is gone (== always 0), I just removed all ~..._disabled.

@@ -242,7 +242,7 @@ RegistryI::startImpl()
}

setupThreadPool(properties, "IceGrid.Registry.Client.ThreadPool", 1, 10);
setupThreadPool(properties, "IceGrid.Registry.Server.ThreadPool", 1, 10, true); // Serialize for admin callbacks
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Do we need to set MaxDispatches=1 on this OA?

It's not immediately clear to me what this is about.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a though one to answer 🙂.

It's about the following: https://doc.zeroc.com/ice/3.7/ice-services/icegrid/icegrid-and-the-administrative-facility#id-.IceGridandtheAdministrativeFacilityv3.7-CallbackswithoutGlacier2

In the example, the status of the services of an IceBox server can be observed by an IceGrid admin client. The IceGrid Admin GUI supports this, it shows the status of services from an IceBox server.

Here, it's important that calls performed by the IceBox server (

p->servicesStartedAsync(services, nullptr, makeObserverCompletedCallback(p));
) to the IceGrid admin client service observer are received in the same order.

These calls are received on the IceGrid registry server endpoints and forwarded to the admin client. The serialize mode ensures that the calls are forwarded in the same order.

So MaxDispatches=1 is indeed needed...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, it's important that calls performed by the IceBox server (...code...) to the IceGrid admin client service observer are received in the same order.

The concern is ServiceManagerI could call servicesStartedAsync and servicesStoppedAsync on the same observer, and we want these non-awaited calls to reach the ultimate observer in the same order?

@@ -26,7 +26,6 @@ CallbackClient::run(int argc, char** argv)
{
auto properties = createTestProperties(argc, argv);
properties->setProperty("Ice.Warn.Connections", "0");
properties->setProperty("Ice.ThreadPool.Client.Serialize", "1");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the Serialize in this test doesn't appear to break the test. What are they for?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing that the server and client exchange a token with the callback, it's most likely to ensure oneway calls ordering. The test should set MaxDispatches=1 instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set MaxDispatches=1 on what?

The CallbackReceiverAdapter?

@@ -14,8 +14,6 @@
"Ice.Warn.Dispatch": "0",
"Ice.Warn.Connections": "0",
"Ice.TCP.SndSize": "100000",
"Ice.ThreadPool.Server.Serialize": "1",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More useless Serialize?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's most likely here because the Glacier2 router is started with --Ice.ThreadPool.Server.SizeMax=3 (like any Ice server from the test suite). So it's useful to ensure that requests from the client are forwared in the same order... MaxDispatches=1 can be used instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we had both Ice.ThreadPool.Server.Serialize AND Ice.ThreadPool.Client.Serialize.

Ice.ThreadPool.Server.Serialize => "serializes" regular requests received by Glacier2 router (on its two OAs, since they don't configure their own thread pools).

Ice.ThreadPool.Client.Serialize => "serializes" bi-dir requests?

Since the test passes even though I didn't configure anything, it's not a good test.

@@ -1443,8 +1443,6 @@ private void setState(int state) {
}
}
// else don't resume reading since we're at or over the _maxDispatches limit.

_threadPool.register(this, SocketOperation.Read);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug in the MaxDispatches implementation (now fixed). Detected by the updated hold test.

{
// Make sure ordering is preserved on each connection.
int counter = 0;
for (int i = 0; i < 10; ++i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of the outer loop, if we wait for the counter before each iteration?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that I just moved this test case to a separate test - didn't change it.

My understanding is the outer loop performs the same testing with 10 different connections. It's clearly not an AAA test.

Copy link
Member

@bentoi bentoi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@@ -242,7 +242,7 @@ RegistryI::startImpl()
}

setupThreadPool(properties, "IceGrid.Registry.Client.ThreadPool", 1, 10);
setupThreadPool(properties, "IceGrid.Registry.Server.ThreadPool", 1, 10, true); // Serialize for admin callbacks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a though one to answer 🙂.

It's about the following: https://doc.zeroc.com/ice/3.7/ice-services/icegrid/icegrid-and-the-administrative-facility#id-.IceGridandtheAdministrativeFacilityv3.7-CallbackswithoutGlacier2

In the example, the status of the services of an IceBox server can be observed by an IceGrid admin client. The IceGrid Admin GUI supports this, it shows the status of services from an IceBox server.

Here, it's important that calls performed by the IceBox server (

p->servicesStartedAsync(services, nullptr, makeObserverCompletedCallback(p));
) to the IceGrid admin client service observer are received in the same order.

These calls are received on the IceGrid registry server endpoints and forwarded to the admin client. The serialize mode ensures that the calls are forwarded in the same order.

So MaxDispatches=1 is indeed needed...

@@ -26,7 +26,6 @@ CallbackClient::run(int argc, char** argv)
{
auto properties = createTestProperties(argc, argv);
properties->setProperty("Ice.Warn.Connections", "0");
properties->setProperty("Ice.ThreadPool.Client.Serialize", "1");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing that the server and client exchange a token with the callback, it's most likely to ensure oneway calls ordering. The test should set MaxDispatches=1 instead.

@@ -14,8 +14,6 @@
"Ice.Warn.Dispatch": "0",
"Ice.Warn.Connections": "0",
"Ice.TCP.SndSize": "100000",
"Ice.ThreadPool.Server.Serialize": "1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's most likely here because the Glacier2 router is started with --Ice.ThreadPool.Server.SizeMax=3 (like any Ice server from the test suite). So it's useful to ensure that requests from the client are forwared in the same order... MaxDispatches=1 can be used instead.

_acceptorStarted = false;
_adapter.getThreadPool().finish(this);
closeAcceptor();
// Ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In many other places, we log as errors unexpected exceptions from the transport implementation.

@bernardnormier
Copy link
Member Author

We'll keep Serialize - using MaxDispatches=1 is not a direct replacement.

@bernardnormier bernardnormier deleted the remove-serialize branch January 21, 2025 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants