docs: public void publish(NDArrayMessage message) throws Exception {
          if (!init)
              init();
          // Create a context, needed for client connection to media driver
          // A separate media driver process needs to be running prior to starting this application
  
          // Create an Aeron instance with client-provided context configuration and connect to the
          // media driver, and create a Publication.  The Aeron and Publication classes implement
          // AutoCloseable, and will automatically clean up resources when this try block is finished.
          boolean connected = false;
          if (aeron == null) {
              try {
                  while (!connected) {
                      aeron = Aeron.connect(ctx);
                      connected = true;
                  }
              } catch (Exception e) {
                  log.warn("Reconnecting on publisher...failed to connect");
              }
          }
  
          int connectionTries = 0;
          while (publication == null && connectionTries < NUM_RETRIES) {
              try {
                  publication = aeron.addPublication(channel, streamId);
                  log.info("Created publication on channel " + channel + " and stream " + streamId);
              } catch (DriverTimeoutException e) {
                  Thread.sleep(1000 * (connectionTries + 1));
                  log.warn("Failed to connect due to driver time out on channel " + channel + " and stream " + streamId
                                  + "...retrying in " + connectionTries + " seconds");
                  connectionTries++;
              }
          }
  
          if (!connected && connectionTries >= 3 || publication == null) {
              throw new IllegalStateException(
                              "Publisher unable to connect to channel " + channel + " and stream " + streamId);
          }
  
  
          // Allocate enough buffer size to hold maximum message length
          // The UnsafeBuffer class is part of the Agrona library and is used for efficient buffer management
          log.info("Publishing to " + channel + " on stream Id " + streamId);
          //ensure default values are set
          INDArray arr = message.getArr();
          if (isCompress())
              while (!message.getArr().isCompressed())
                  Nd4j.getCompressor().compressi(arr, "GZIP");
  
  
  
          //array is large, need to segment
          if (NDArrayMessage.byteBufferSizeForMessage(message) >= publication.maxMessageLength()) {
              NDArrayMessageChunk[] chunks = NDArrayMessage.chunks(message, publication.maxMessageLength() / 128);
              for (int i = 0; i < chunks.length; i++) {
                  ByteBuffer sendBuff = NDArrayMessageChunk.toBuffer(chunks[i]);
                  sendBuff.rewind();
                  DirectBuffer buffer = new UnsafeBuffer(sendBuff);
                  sendBuffer(buffer);
              }
          } else {
              //send whole array
              DirectBuffer buffer = NDArrayMessage.toBuffer(message);
              sendBuffer(buffer);
  
          }
  
      }