[ 
https://issues.apache.org/jira/browse/BEAM-13159?focusedWorklogId=695769&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-695769
 ]

ASF GitHub Bot logged work on BEAM-13159:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 14/Dec/21 13:39
            Start Date: 14/Dec/21 13:39
    Worklog Time Spent: 10m 
      Work Description: aromanenko-dev commented on a change in pull request 
#15858:
URL: https://github.com/apache/beam/pull/15858#discussion_r768673840



##########
File path: 
sdks/java/io/redis/src/main/java/org/apache/beam/sdk/io/redis/RedisIO.java
##########
@@ -709,4 +720,146 @@ public void teardown() {
       }
     }
   }
+
+  /**
+   * A {@link PTransform} to write stream key pairs 
(https://redis.io/topics/streams-intro) to a
+   * Redis server.
+   */
+  @AutoValue
+  public abstract static class WriteStreams
+      extends PTransform<PCollection<KV<String, Map<String, String>>>, PDone> {
+
+    abstract @Nullable RedisConnectionConfiguration connectionConfiguration();
+
+    abstract @Nullable Long maxLen();
+
+    abstract boolean approximateTrim();
+
+    abstract Builder toBuilder();
+
+    @AutoValue.Builder
+    abstract static class Builder {
+
+      abstract Builder setConnectionConfiguration(
+          RedisConnectionConfiguration connectionConfiguration);
+
+      abstract Builder setMaxLen(Long maxLen);
+
+      abstract Builder setApproximateTrim(boolean approximateTrim);
+
+      abstract WriteStreams build();
+    }
+
+    public WriteStreams withEndpoint(String host, int port) {
+      checkArgument(host != null, "host can not be null");
+      checkArgument(port > 0, "port can not be negative or 0");
+      return toBuilder()
+          
.setConnectionConfiguration(connectionConfiguration().withHost(host).withPort(port))
+          .build();
+    }
+
+    public WriteStreams withAuth(String auth) {
+      checkArgument(auth != null, "auth can not be null");
+      return toBuilder()
+          .setConnectionConfiguration(connectionConfiguration().withAuth(auth))
+          .build();
+    }
+
+    public WriteStreams withTimeout(int timeout) {
+      checkArgument(timeout >= 0, "timeout can not be negative");
+      return toBuilder()
+          
.setConnectionConfiguration(connectionConfiguration().withTimeout(timeout))
+          .build();
+    }
+
+    public WriteStreams 
withConnectionConfiguration(RedisConnectionConfiguration connection) {
+      checkArgument(connection != null, "connection can not be null");
+      return toBuilder().setConnectionConfiguration(connection).build();
+    }
+
+    public WriteStreams withMaxLen(Long maxLen) {
+      checkArgument(maxLen >= 0L, "maxLen must be positive if set");
+      return toBuilder().setMaxLen(maxLen).build();
+    }
+
+    public WriteStreams withApproximateTrim(boolean approximateTrim) {
+      return toBuilder().setApproximateTrim(approximateTrim).build();
+    }
+
+    @Override
+    public PDone expand(PCollection<KV<String, Map<String, String>>> input) {
+      checkArgument(connectionConfiguration() != null, 
"withConnectionConfiguration() is required");
+
+      input.apply(ParDo.of(new WriteStreamFn(this)));
+      return PDone.in(input.getPipeline());
+    }
+
+    private static class WriteStreamFn extends DoFn<KV<String, Map<String, 
String>>, Void> {
+
+      private static final int DEFAULT_BATCH_SIZE = 1000;
+
+      private final WriteStreams spec;
+
+      private transient Jedis jedis;
+      private transient Pipeline pipeline;
+
+      private int batchCount;
+
+      public WriteStreamFn(WriteStreams spec) {
+        this.spec = spec;
+      }
+
+      @Setup
+      public void setup() {
+        jedis = spec.connectionConfiguration().connect();
+      }
+
+      @StartBundle
+      public void startBundle() {
+        pipeline = jedis.pipelined();
+        pipeline.multi();
+        batchCount = 0;
+      }
+
+      @ProcessElement
+      public void processElement(ProcessContext c) {
+        KV<String, Map<String, String>> record = c.element();
+
+        writeRecord(record);
+
+        batchCount++;
+
+        if (batchCount >= DEFAULT_BATCH_SIZE) {
+          pipeline.exec();
+          pipeline.sync();
+          pipeline.multi();
+          batchCount = 0;
+        }
+      }
+
+      private void writeRecord(KV<String, Map<String, String>> record) {
+        String key = record.getKey();
+        Map<String, String> value = record.getValue();
+        if (spec.maxLen() > 0L) {
+          pipeline.xadd(key, StreamEntryID.NEW_ENTRY, value, spec.maxLen(), 
spec.approximateTrim());
+        } else {
+          pipeline.xadd(key, StreamEntryID.NEW_ENTRY, value);
+        }
+      }
+
+      @FinishBundle
+      public void finishBundle() {
+        if (pipeline.isInMulti()) {
+          pipeline.exec();

Review comment:
       I'd propose to create a separate Jira issue for error handling 
refactoring.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Issue Time Tracking
-------------------

    Worklog Id:     (was: 695769)
    Time Spent: 11h 20m  (was: 11h 10m)

> Support for Redis 5.0 streams (XADD/XREAD/XRANGE) in RedisIO
> ------------------------------------------------------------
>
>                 Key: BEAM-13159
>                 URL: https://issues.apache.org/jira/browse/BEAM-13159
>             Project: Beam
>          Issue Type: New Feature
>          Components: io-java-redis
>            Reporter: N. M.
>            Assignee: N. M.
>            Priority: P2
>          Time Spent: 11h 20m
>  Remaining Estimate: 0h
>
> Redis 5.0 and later support an append-only log data structure called a 
> "stream" -- each element has a unique incrementing ID and contains one or 
> more string:string key-value pairs.
> This seems like a gimme for a stream processing platform to support, and in 
> fact Jedis already has support for XADD/XREAD/XRANGE in it, but the current 
> redisIO Read and Write classes only support pcollections of single KVs and 
> thus will need some additional work to support streams.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to