@Test
  public void testClientFunctionExecutionTimingOutDoesNotLeaveServerConnectionThreadsHanged() {
    // Set client connect-timeout to a very high value so that if there are no
    // ServerConnection threads available the test will time-out before the client times-out.
    int connectTimeout = (int) (GeodeAwaitility.getTimeout().toMillis() * 2);
    int maxThreads = 2;
    createScenarioWithClientConnectTimeout(connectTimeout, maxThreads);

    // The function must be executed a number of times equal
    // to the number of servers * the max-threads, to check if all the
    // threads are hanged.
    int executions = (3 * maxThreads);

    // functionTimeoutSecs should be lower than the
    // time taken by the slow function to return all
    // the results
    int functionTimeoutSecs = 2;

    Function<?> function = new TestFunction<>(true, TestFunction.TEST_FUNCTION_SLOW);
    registerFunctionAtServer(function);

    // Run the function that will time-out at the client
    // the number of specified times.
    IntStream.range(0, executions)
        .forEach(i -> assertThatThrownBy(() -> client
            .invoke(() -> executeSlowFunctionOnRegionNoFilter(function, PartitionedRegionName,
                functionTimeoutSecs)))
                    .getCause().getCause().isInstanceOf(ServerConnectivityException.class));

    // Make sure that the get returns timely. If it hangs, it means
    // that there are no threads available in the servers to handle the
    // request because they were hanged due to the previous function
    // executions.
    await().until(() -> {
      client.invoke(() -> executeGet(PartitionedRegionName, "key"));
      return true;
    });
  }
This test case verifies that if the execution of a function handled
by a Function Execution thread times out at the client, the ServerConnection
thread will eventually be released.
In order to test this, a slow function will be executed by a client
with a small time-out a number of times equal to the number of servers
in the cluster * the max number of threads configured.
After the function executions have timed-out, another request will be
sent by the client to any server and it should be served timely.
If the ServerConnection threads had not been released, this new
request will never be served because there would be not ServerConnection
threads available and the test case will time-out.
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/execute/PRClientServerRegionFunctionExecutionNoSingleHopDistributedTest.java