docs: public static void main(String[] args) throws Exception {
      Builder processingGraphBuilder = Builder.newBuilder();
  
      Streamlet<Integer> randomIntegers = processingGraphBuilder
          .newSource(() -> {
            // Random integers are emitted every 50 milliseconds
            StreamletUtils.sleep(50);
            return ThreadLocalRandom.current().nextInt(100);
          })
          .setNumPartitions(2)
          .setName("random-integer-source");
  
      randomIntegers
          // The specific repartition logic is applied here
          .repartition(8, RepartitionTopology::repartitionStreamlet)
          .setName("repartition-incoming-values")
          // Here, a generic repartition logic is applied (simply
          // changing the number of partitions without specifying
          // how repartitioning will take place)
          .repartition(2)
          .setName("reduce-partitions-for-logging-operation")
          .log();
  
      // Fetches the topology name from the first command-line argument
      String topologyName = StreamletUtils.getTopologyName(args);
  
      Config config = Config.defaultConfig();
  
      // Finally, the processing graph and configuration are passed to the Runner, which converts
      // the graph into a Heron topology that can be run in a Heron cluster.
      new Runner().run(topologyName, config, processingGraphBuilder);
    }