code: def make_requests_concurrently(
      client: cx.Client,
      api_name: str,
      concurrency: int,
      event_stopper: td.Event,
      latencies: Optional[List[float]] = None,
      responses: Optional[List[Dict[str, Any]]] = None,
      max_total_requests: Optional[int] = None,
      payload: Optional[Union[List, Dict]] = None,
      query_params: Dict[str, str] = {},
  ) -> List[futures.Future]:
      lock = td.RLock()
      thread_local = td.local()
      start_sync = td.Barrier(concurrency)
      end_sync = td.Barrier(concurrency)
      executor = futures.ThreadPoolExecutor(concurrency)
      api_info = client.get_api(api_name)
      endpoint = api_info["endpoint"]
  
      global _make_requests_concurrently_max_total_requests
      _make_requests_concurrently_max_total_requests = (
          max_total_requests
      )
  
      def get_session() -> requests.Session:
          if not hasattr(thread_local, "session"):
              thread_local.session = requests.Session()
          return thread_local.session
  
      def runnable():
          session = get_session()
          global _make_requests_concurrently_max_total_requests
          start_sync.wait()
          while not event_stopper.is_set():
              if (
                  _make_requests_concurrently_max_total_requests
                  is not None
              ):
                  with lock:
                      if (
                          _make_requests_concurrently_max_total_requests
                          == 0
                      ):
                          break
                      _make_requests_concurrently_max_total_requests -= (
                          1
                      )
              start = time.time()
              response = session.post(
                  endpoint, json=payload, params=query_params
              )
              assert (
                  response.status_code == HTTPStatus.OK
              ), f"status code: got {response.status_code}, expected {HTTPStatus.OK}"
              if latencies is not None:
                  latencies.append(time.time() - start)
              if responses is not None:
                  responses.append(response)
  
          if _make_requests_concurrently_max_total_requests is not None:
              end_sync.wait()
              event_stopper.set()
  
      futures_list = []
      for _ in range(concurrency):
          future = executor.submit(runnable)
          futures_list.append(future)
  
      return futures_list
  
imports: import os
  import threading
  import time
  from concurrent import futures
  from http import HTTPStatus
  from typing import Any, List, Optional, Tuple, Union, Dict, Callable
  import cortex
  import requests
  import yaml
label_desc: Use image node_id 14 for calling a global function with example usage: make_requests_concurrently(client, api_name, concurrency, event_stopper, latencies, responses, max_total_requests, payload, query_params) and returns: futures_list, thread_local