docstr: Creates a zmq socket on a random port.
  
  :param context: zmq context
  :param socket_type: zmq socket type
  :return: A tuple: ``(zmq_socket, endpoint_address)``
docstr_tok: ["Creates","a","zmq","socket","on","a","random","port",".",":","param","context",":","zmq","context",":","param","socket_type",":","zmq","socket","type",":","return",":","A","tuple",":","``","(","zmq_socket",",","endpoint_address",")","``"]
code: def _create_local_socket_on_random_port(self, context, socket_type):
      """Creates a zmq socket on a random port.
  
      :param context: zmq context
      :param socket_type: zmq socket type
      :return: A tuple: ``(zmq_socket, endpoint_address)``
      """
      LOCALHOST = "tcp://127.0.0.1"
      socket = context.socket(socket_type)
  
      # There are race conditions where the socket can close when messages are still trying to be sent by zmq.
      # This can end up causing zmq to block indefinitely when sending objects or shutting down. Having the socket
      # linger on close helps prevent this.
      socket.linger = _SOCKET_LINGER_MS
  
      port = socket.bind_to_random_port(LOCALHOST)
      return socket, "{}:{}".format(LOCALHOST, port)
  
imports: import logging
  import pickle
  import sys
  import os
  from time import sleep, time
  from traceback import format_exc
  from threading import Thread
  from psutil import pid_exists
  import zmq
  from zmq import ZMQBaseError
  from petastorm.reader_impl.pickle_serializer import PickleSerializer
  from petastorm.workers_pool import EmptyResultError, VentilatedItemProcessedMessage
  from petastorm.workers_pool.exec_in_new_process import exec_in_new_process
label_desc: Use image node_id 2 for calling the ProcessPool obj's underlying member method code with example usage: obj._create_local_socket_on_random_port(context, socket_type) and returns: socket,  str