Fix port binding race between sequential GLV integration test runs

docker compose down can return before docker-proxy has fully released its socket bindings. Since all four GLV modules share host ports 45940-45942 and 4588 and Maven runs them sequentially, the next module would intermittently fail to bind those ports. After each module's final compose down, poll sstlnp for up to 30 seconds until all four ports are confirmed free before returning control to Maven. CTR
diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml
index 13ebf54..d7d9f88 100644
--- a/gremlin-dotnet/test/pom.xml
+++ b/gremlin-dotnet/test/pom.xml
@@ -103,9 +103,21 @@
                                         <HOME>${user.home}</HOME>
                                     </environmentVariables>
                                     <executable>bash</executable>
+                                    <!--
+                                    Command breakdown:
+                                      compose down (first)   - remove any containers left over from a previously failed run
+                                      compose up             - build images, start the server and test containers,
+                                                               and wait for the test container to finish
+                                      compose down (second)  - tear down this run's containers and network
+                                      port-wait loop         - wait up to 30 s for ports 45940-45942 and 4588 to be released by
+                                                               the Docker daemon before returning to Maven; all GLV modules share
+                                                               these host ports and run sequentially, so the next module would
+                                                               fail to bind them if docker-proxy has not fully exited yet
+                                      image prune            - remove dangling test images to reclaim disk space
+                                    -->
                                     <arguments>
                                         <argument>-c</argument>
-                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-dotnet-integration-tests; EXIT=$?; docker compose down; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
+                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-dotnet-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
                                     </arguments>
                                 </configuration>
                             </execution>
diff --git a/gremlin-go/pom.xml b/gremlin-go/pom.xml
index 41413b2..5d5019a 100644
--- a/gremlin-go/pom.xml
+++ b/gremlin-go/pom.xml
@@ -114,9 +114,21 @@
                                         <HOME>${user.home}</HOME>
                                     </environmentVariables>
                                     <executable>bash</executable>
+                                    <!--
+                                    Command breakdown:
+                                      compose down (first)   - remove any containers left over from a previously failed run
+                                      compose up             - build images, start the server and test containers,
+                                                               and wait for the test container to finish
+                                      compose down (second)  - tear down this run's containers and network
+                                      port-wait loop         - wait up to 30 s for ports 45940-45942 and 4588 to be released by
+                                                               the Docker daemon before returning to Maven; all GLV modules share
+                                                               these host ports and run sequentially, so the next module would
+                                                               fail to bind them if docker-proxy has not fully exited yet
+                                      image prune            - remove dangling test images to reclaim disk space
+                                    -->
                                     <arguments>
                                         <argument>-c</argument>
-                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-go-integration-tests; EXIT=$?; docker compose down; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
+                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-go-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
                                     </arguments>
                                 </configuration>
                             </execution>
diff --git a/gremlin-js/gremlin-javascript/pom.xml b/gremlin-js/gremlin-javascript/pom.xml
index fcbab8a..f2dd798 100644
--- a/gremlin-js/gremlin-javascript/pom.xml
+++ b/gremlin-js/gremlin-javascript/pom.xml
@@ -282,9 +282,21 @@
                                         <HOST_GID>${host.gid}</HOST_GID>
                                     </environmentVariables>
                                     <executable>bash</executable>
+                                    <!--
+                                    Command breakdown:
+                                      compose down (first)   - remove any containers left over from a previously failed run
+                                      compose up             - build images, start the server and test containers,
+                                                               and wait for the test container to finish
+                                      compose down (second)  - tear down this run's containers and network
+                                      port-wait loop         - wait up to 30 s for ports 45940-45942 and 4588 to be released by
+                                                               the Docker daemon before returning to Maven; all GLV modules share
+                                                               these host ports and run sequentially, so the next module would
+                                                               fail to bind them if docker-proxy has not fully exited yet
+                                      image prune            - remove dangling test images to reclaim disk space
+                                    -->
                                     <arguments>
                                         <argument>-c</argument>
-                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-js-integration-tests; EXIT=$?; docker compose down; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
+                                        <argument>docker compose down; docker compose up --build --exit-code-from gremlin-js-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT</argument>
                                     </arguments>
                                     <workingDirectory>.</workingDirectory>
                                 </configuration>
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 40d8ad8..9ef88c1 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -155,7 +155,17 @@
                             </execution>
 
                             <!--
-                            use docker compose to run unit tests, radish, and integration tests.
+                            Use docker compose to run unit tests, radish, and integration tests.
+                            Command breakdown:
+                              compose down (first)   - remove any containers left over from a previously failed run
+                              compose up             - build images, start the server and test containers,
+                                                       and stop everything when either container exits
+                              compose down (second)  - tear down this run's containers and network
+                              port-wait loop         - wait up to 30 s for ports 45940-45942 and 4588 to be released by
+                                                       the Docker daemon before returning to Maven; all GLV modules share
+                                                       these host ports and run sequentially, so the next module would
+                                                       fail to bind them if docker-proxy has not fully exited yet
+                              image prune            - remove dangling test images to reclaim disk space
                             -->
                             <execution>
                                 <id>python-tests</id>
@@ -174,7 +184,7 @@
                                             <env key="PYTEST_ARGS" value="${pytestArgs}"/>
                                             <env key="RADISH_ARGS" value="${radishArgs}"/>
                                             <arg value="-c"/>
-                                            <arg value="docker compose down; docker compose up --build --abort-on-container-exit gremlin-server-test-python gremlin-python-integration-tests; EXIT=$?; docker compose down; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT"/>
+                                            <arg value="docker compose down; docker compose up --build --abort-on-container-exit gremlin-server-test-python gremlin-python-integration-tests; EXIT=$?; docker compose down; for i in $(seq 1 30); do ss -tlnp | grep -qE ':(45940|45941|45942|4588) ' || break; sleep 1; done; docker image prune --filter label=maintainer=dev@tinkerpop.apache.org -f; exit $EXIT"/>
                                         </exec>
                                     </target>
                                 </configuration>