code: public <T> T sendMessage(Address dest, Buffer data, RequestOptions opts) throws Exception {
          if(dest == null)
              throw new IllegalArgumentException("message destination is null, cannot send message");
  
          if(opts == null) {
              log.warn("request options were null, using default of sync");
              opts=RequestOptions.SYNC();
          }
  
          // invoke an async RPC directly and return null, without creating a UnicastRequest instance
          if(opts.mode() == ResponseMode.GET_NONE) {
              rpc_stats.add(RpcStats.Type.UNICAST, dest, false, 0);
              corr.sendUnicastRequest(dest, data, null, opts);
              return null;
          }
  
          // now it must be a sync RPC
          UnicastRequest<T> req=new UnicastRequest<>(corr, dest, opts);
          long start=!rpc_stats.extendedStats()? 0 : System.nanoTime();
          try {
              return req.execute(data, true);
          }
          finally {
              long time=!rpc_stats.extendedStats()? 0 : System.nanoTime() - start;
              rpc_stats.add(RpcStats.Type.UNICAST, dest, true, time);
          }
      }
docs: Sends a unicast message and - depending on the options - returns a result
  @param dest the target to which to send the unicast message. Must not be null.
  @param data the payload to send
  @param opts the options to be used
  @return T the result. Null if the call is asynchronous (non-blocking) or if the response is null
  @throws Exception If there was problem sending the request, processing it at the receiver, or processing
  it at the sender.
  @throws TimeoutException If the call didn't succeed within the timeout defined in options (if set)