text: import zmq
  import time
  import socket
  
  
  def dataKeeper(NodeIndex, processesIndex, startingPortDatakeeperClient, masterCount, masterIP, datakeeperIP):
      print("Datakeeper index = " + str(processesIndex))
  
      address = {"ip": "" + datakeeperIP + "", "nodeIndex": NodeIndex,
                 "head": True if processesIndex == 0 else False}
      context1 = zmq.Context()
      ipSender = context1.socket(zmq.PUSH)
      ipSender.connect("tcp://" + masterIP + ":%s" % str(17777))
      ipSender.send_pyobj(address)
      #print("Ana datakeeper b3at le ip: tcp://" + masterIP + ":%s" % str(17777))
      context = zmq.Context()
      if processesIndex == 0:
          port = 5556+NodeIndex
          socket = context.socket(zmq.PUB)
          socket.bind("tcp://" + datakeeperIP + ":%s" % str(port))
          start = time.time()
          #testingTimer = time.time()
  
      # Bind ports of datakeeper to be used with client
      context2 = zmq.Context()
      clientSocket = context2.socket(zmq.PAIR)
      clientSocket.bind("tcp://" + datakeeperIP + ":" +
                        str(int(startingPortDatakeeperClient+processesIndex)))
      clientSocket.RCVTIMEO = 1
  
      # connect ports of datakeeper to send To Master
      context4 = zmq.Context()
      dksocket = context4.socket(zmq.REQ)  # client
      for i in range(masterCount):  # connect Datakeeper to all Masters sockets
          port = 15000+i
          dksocket.connect("tcp://" + masterIP + ":%s" % port)
      # connect ports of datakeeper to be used with Master
      context3 = zmq.Context()
      masterSocket = context3.socket(zmq.SUB)
      masterSocket.RCVTIMEO = 1
  
      for i in range(masterCount):  # connect Datakeeper to all Masters sockets
          port = 10000+i
          # hena el mafrood no7ot el ip bta3 el master
          masterSocket.connect("tcp://" + masterIP + ":%s" % port)
      topicfilter = "1"
      masterSocket.setsockopt_string(zmq.SUBSCRIBE, topicfilter)
      print("----------------------------------------------------------------------------------")
      print("-- Datakeeper connected to all master processes successfully (n-replicates) !!! --")
      print("----------------------------------------------------------------------------------")
  
      while True:
          if processesIndex == 0:
              if (time.time()-start >= 1):
                  topic = 1  # topic ( I am Alive messages)
                  messagedata = 1  # alive
                  ip = datakeeperIP
                  socket.send_string("%d %d %s %d %d" % (
                      topic, messagedata, ip, NodeIndex, processesIndex))
                  start = time.time()
              # if time.time() - testingTimer >= 3+NodeIndex:
                  # break
  
          # Connection with client
          data = []
          try:
              data = clientSocket.recv_pyobj()
          except zmq.error.Again:
              pass
  
          # Nreplicates connection with master
          data3 = []
          topic = "0"
          messagedata = [None] * 5
          try:
             # print ("try to recive from master \n")
              data3 = masterSocket.recv_string()
              #print ("recieved from master to srcmachine", data3)
              topic, messagedata[0], messagedata[1], messagedata[2], messagedata[3], messagedata[4] = data3.split(
              )
          except zmq.error.Again:
              pass
  
          # message from Master to sourceMachine dataKeeper here source machine datakeeper send the video to another data keeper so at machine_to_copy it will get in "client upload" as if a client send this file to it
          if topic == "1" and len(messagedata) == 5:
              if messagedata[2] == "source_machine" and messagedata[3] == "tcp://" + datakeeperIP + ":" and messagedata[4] == str(processesIndex+8000):
                  #print("sending to Machine to copy")
                  contextt = zmq.Context()
                  # Datakeeper-Datakeeper connection
                  datakeeperSocket = contextt.socket(zmq.PAIR)
                  datakeeperSocket.connect(messagedata[0])
                  f = open(messagedata[1], 'rb')
                  video = f.read()
                  datakeeperSocket.send_pyobj([video, messagedata[1]])
                  #print("sent to Machine to copy")
                  f.close()
                  a = datakeeperSocket.recv()
                  # print(a)
  
                  "---------------------------------To handle Source machine busy---------------------------------------"
                  tocheck = 3
                  ip = messagedata[3]
                  port = messagedata[4]
                  fileName = "a"
                  dksocket.send_string(" %d %s %s %s" %
                                       (tocheck, ip, port, fileName))
                  dksocket.recv_string()
                  "-------------------------------------------------------------------------------------------------------"
          if len(data) == 2:    # Client upload
              # To download in the same location of the file
              name = data[1].split("/")
              f = open(name[-1], 'wb')
              f.write(data[0])
              f.close()
              print("File uploaded successfully")
              # send to master that it is successfully uploaded
              # --------------------------------------------------------------------------------------
              topic = 1
              messagedata = 2
              fileName = name[-1]
              ip = datakeeperIP
              print(fileName)
              port = str(int(startingPortDatakeeperClient+processesIndex))
              dksocket.send_string("%d %s %s %s" %
                                   (messagedata, ip, port, fileName))
              dksocket.recv()
              # --------------------------------------------------------------------------------------------
              clientSocket.send_string("done recieving")
  
          elif len(data) == 1:  # Client download
              f = open(data[0], 'rb')
              video = f.read()
              clientSocket.send_pyobj([video, data[0]])
              f.close()
  
  