Java Code Examples for reactor.core.publisher.Flux#defer()

The following examples show how to use reactor.core.publisher.Flux#defer() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: r2dbc-mysql   File: QueryFlow.java    License: Apache License 2.0 6 votes vote down vote up
static Flux<Flux<ServerMessage>> execute(Client client, TextQuery query, List<Binding> bindings) {
    switch (bindings.size()) {
        case 1: // Most case.
            return Flux.defer(() -> execute0(client, query, bindings.get(0)).windowUntil(RESULT_DONE));
        case 0:
            return Flux.empty();
        default:
            Iterator<Binding> iter = bindings.iterator();
            EmitterProcessor<Binding> processor = EmitterProcessor.create(1, true);
            Runnable complete = () -> OperatorUtils.emitIterator(processor, iter);

            processor.onNext(iter.next());

            return processor.concatMap(it -> execute0(client, query, it).doOnComplete(complete))
                .doOnCancel(() -> Binding.clearSubsequent(iter))
                .doOnError(ignored -> Binding.clearSubsequent(iter))
                .windowUntil(RESULT_DONE);
    }
}
 
Example 2
@Override
public Flux<Message> subscribe(SubscribeRequest request) {
    return Flux.defer(() -> {
        try {
            Map<String, String> variables = MqttTopicUtils.getPathVariables(
                "/dashboard/{dashboard}/{object}/{measurement}/{dimension}", request.getTopic());
            return dashboardManager.getDashboard(variables.get("dashboard"))
                .flatMap(dashboard -> dashboard.getObject(variables.get("object")))
                .flatMap(object -> object.getMeasurement(variables.get("measurement")))
                .flatMap(measurement -> measurement.getDimension(variables.get("dimension")))
                .flatMapMany(dimension -> dimension.getValue(MeasurementParameter.of(request.getParameter())))
                .map(val -> Message.success(request.getId(), request.getTopic(), val));
        } catch (Exception e) {
            return Flux.error(new IllegalArgumentException("topic格式错误,正确格式:/dashboard/{dashboard}/{object}/{measurement}/{dimension}", e));
        }
    });
}
 
Example 3
@Override
public final Flux<MySqlResult> execute() {
    if (bindings.bindings.isEmpty()) {
        throw new IllegalStateException("No parameters bound for current statement");
    }
    bindings.validatedFinish();

    return Flux.defer(() -> {
        if (!executed.compareAndSet(false, true)) {
            return Flux.error(new IllegalStateException("Parametrized statement was already executed"));
        }

        return execute(bindings.bindings);
    });
}
 
Example 4
@Override
public Flux<MySqlResult> execute() {
    return Flux.defer(() -> QueryFlow.prepare(client, sql)
        .flatMapMany(it -> QueryFlow.execute(client, context, sql, it, deprecateEof, fetchSize, BINDINGS)
            .map(messages -> new MySqlResult(true, codecs, context, generatedKeyName, messages))
            .onErrorResume(e -> it.close().then(Mono.error(e)))
            .concatWith(it.close().then(Mono.empty()))
            .doOnCancel(() -> it.close().subscribe())));
}
 
Example 5
@Override
public Flux<ClusterMembershipEvent> membershipChangeEvents() {
    return Flux.defer(() -> {
        AtomicBoolean firstEmit = new AtomicBoolean(true);
        return reconciler.changes()
                .flatMap(update -> firstEmit.getAndSet(false)
                        ? Flux.just(update.getSnapshotEvent())
                        : Flux.fromIterable(update.getDeltaEvents())
                );
    });
}
 
Example 6
Source Project: r2dbc-mysql   File: MySqlResult.java    License: Apache License 2.0 5 votes vote down vote up
private Flux<ServerMessage> results() {
    return Flux.defer(() -> {
        Flux<ServerMessage> messages = this.messages.getAndSet(null);

        if (messages == null) {
            return Flux.error(new IllegalStateException("Source has been released"));
        }

        // Result mode, no need ok message.
        this.okProcessor.onComplete();

        return OperatorUtils.discardOnCancel(messages).doOnDiscard(ReferenceCounted.class, RELEASE);
    });
}
 
Example 7
@Override
protected Flux<ReplicatorEvent<TaskRelocationSnapshot, TaskRelocationEvent>> newConnection() {
    return Flux.defer(() -> {
        CacheUpdater cacheUpdater = new CacheUpdater();
        logger.info("Connecting to the task relocation event stream...");
        return client.events(TaskRelocationQuery.getDefaultInstance()).flatMap(cacheUpdater::onEvent);
    });
}
 
Example 8
@Override
public final Flux<MySqlResult> execute() {
    if (bindings.bindings.isEmpty()) {
        throw new IllegalStateException("No parameters bound for current statement");
    }
    bindings.validatedFinish();

    return Flux.defer(() -> {
        if (!executed.compareAndSet(false, true)) {
            return Flux.error(new IllegalStateException("Parametrized statement was already executed"));
        }

        return execute(bindings.bindings);
    });
}
 
Example 9
public Flux<String> serviceAddressFor(String service) {
  return Flux.defer(() ->  Flux.just(this.dClient.getInstances(service)).flatMap(srv ->
      Mono.just(this.lbClient.choose(service))
  ).flatMap(serviceInstance ->
      Mono.just(serviceInstance.getUri().toString())
  ));
}
 
Example 10
public Flux<String> serviceAddressFor(String service) {
  return Flux.defer(() ->  Flux.just(this.dClient.getInstances(service)).flatMap(srv ->
      Mono.just(this.lbClient.choose(service))
  ).flatMap(serviceInstance ->
      Mono.just(serviceInstance.getUri().toString())
  ));
}
 
Example 11
@Override
public Flux<MySqlResult> execute() {
    return Flux.defer(() -> QueryFlow.prepare(client, sql)
        .flatMapMany(it -> QueryFlow.execute(client, context, sql, it, deprecateEof, fetchSize, BINDINGS)
            .map(messages -> new MySqlResult(true, codecs, context, generatedKeyName, messages))
            .onErrorResume(e -> it.close().then(Mono.error(e)))
            .concatWith(it.close().then(Mono.empty()))
            .doOnCancel(() -> it.close().subscribe())));
}
 
Example 12
Source Project: r2dbc-mysql   File: ClobCodec.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public Flux<ByteBuf> publishBinary() {
    return Flux.defer(() -> {
        Clob clob = this.clob.getAndSet(null);

        if (clob == null) {
            return Mono.error(new IllegalStateException("Clob has written, can not write twice"));
        }

        // Must have defaultIfEmpty, try Mono.fromCallable(() -> null).flux().collectList()
        return Flux.from(clob.stream())
            .collectList()
            .defaultIfEmpty(Collections.emptyList())
            .flatMapIterable(list -> {
                if (list.isEmpty()) {
                    // It is zero of var int, not terminal.
                    return Collections.singletonList(allocator.buffer(Byte.BYTES).writeByte(0));
                }

                long bytes = 0;
                Charset charset = context.getClientCollation().getCharset();
                List<ByteBuf> buffers = new ArrayList<>();
                ByteBuf lastBuf = allocator.buffer();

                try {
                    ByteBuf firstBuf = lastBuf;

                    buffers.add(firstBuf);
                    VarIntUtils.reserveVarInt(firstBuf);

                    for (CharSequence src : list) {
                        int length = src.length();

                        if (length > 0) {
                            // size + lastBuf.readableBytes() > MAX_MERGE, it just a minimum estimate.
                            if (length > MAX_MERGE - lastBuf.readableBytes()) {
                                lastBuf = allocator.buffer();
                                buffers.add(lastBuf);
                            }

                            bytes += lastBuf.writeCharSequence(src, charset);
                        }
                    }

                    VarIntUtils.setReservedVarInt(firstBuf, bytes);

                    return BlobCodec.toList(buffers);
                } catch (Throwable e) {
                    BlobCodec.releaseAll(buffers, lastBuf);
                    throw e;
                }
            });
    });
}
 
Example 13
@GetMapping("/timeout")
public Flux<?> timeout() {
	return Flux.defer(() -> Flux.<String>create(emitter -> {
		emitter.next("foo");
	}).timeout(Duration.ofMillis(100L), Flux.empty()));
}
 
Example 14
Source Project: micrometer   File: BufferingFlux.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Creates a Flux that implements Nagle's algorithm to buffer messages -- joined by a delimiter string -- to up a
 * maximum number of bytes, or a maximum duration of time. This avoids sending many small packets in favor of fewer
 * larger ones.
 *
 * @param source                      The input flux.
 * @param delimiter                   The delimiter to use to join messages
 * @param maxByteArraySize            The buffered payload will contain no more than this number of bytes
 * @param maxMillisecondsBetweenEmits Buffered payloads will be emitted no less frequently than this.
 * @return A flux implementing Nagle's algorithm.
 * @see <a href="https://en.wikipedia.org/wiki/Nagle%27s_algorithm">Nagle's algorithm</a>
 */
public static Flux<String> create(final Flux<String> source, final String delimiter, final int maxByteArraySize, final long maxMillisecondsBetweenEmits) {
    return Flux.defer(() -> {
        final int delimiterSize = delimiter.getBytes().length;
        final AtomicInteger byteSize = new AtomicInteger(0);
        final AtomicLong lastTime = new AtomicLong(0);

        final DirectProcessor<Void> intervalEnd = DirectProcessor.create();

        final Flux<String> heartbeat = Flux.interval(Duration.ofMillis(maxMillisecondsBetweenEmits))
                .map(l -> "")
                .takeUntilOther(intervalEnd);

        // Create a stream that emits at least once every $maxMillisecondsBetweenEmits, to avoid long pauses between
        // buffer flushes when the source doesn't emit for a while.
        final Flux<String> sourceWithEmptyStringKeepAlive = source
                .doOnTerminate(intervalEnd::onComplete)
                .mergeWith(heartbeat);

        return sourceWithEmptyStringKeepAlive
                .bufferUntil(line -> {
                    final int bytesLength = line.getBytes().length;
                    final long now = System.currentTimeMillis();
                    // Update last time to now if this is the first time
                    lastTime.compareAndSet(0, now);
                    final long last = lastTime.get();
                    long diff;
                    if (last != 0L) {
                        diff = now - last;
                        if (diff > maxMillisecondsBetweenEmits && byteSize.get() > 0) {
                            // This creates a buffer, reset size
                            byteSize.set(bytesLength);
                            lastTime.compareAndSet(last, now);
                            return true;
                        }
                    }

                    int additionalBytes = bytesLength;
                    if (additionalBytes > 0 && byteSize.get() > 0) {
                        additionalBytes += delimiterSize;  // Make up for the delimiter that's added when joining the strings
                    }

                    final int projectedBytes = byteSize.addAndGet(additionalBytes);

                    if (projectedBytes > maxByteArraySize) {
                        // This creates a buffer, reset size
                        byteSize.set(bytesLength);
                        lastTime.compareAndSet(last, now);
                        return true;
                    }

                    return false;
                }, true)
                .map(lines -> lines.stream()
                        .filter(line -> !line.isEmpty())
                        .collect(Collectors.joining(delimiter, "", delimiter)));
    });
}
 
Example 15
Source Project: r2dbc-mysql   File: QueryFlow.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Execute multiple bindings of a prepared statement with one-by-one. Query execution terminates with
 * the last {@link CompleteMessage} or a {@link ErrorMessage}. The {@link ErrorMessage} will emit an
 * exception and cancel subsequent bindings execution.
 * <p>
 * It will not close this prepared statement.
 *
 * @param client       the {@link Client} to exchange messages with.
 * @param context      the connection context.
 * @param sql          the original statement for exception tracing.
 * @param identifier   the statement identifier want to execute.
 * @param deprecateEof EOF has been deprecated.
 * @param fetchSize    the size of fetching, if it less than or equal to {@literal 0} means fetch all rows.
 * @param bindings     the data of bindings.
 * @return the messages received in response to this exchange, and will be completed
 * by {@link CompleteMessage} when it is last result for each binding.
 */
static Flux<Flux<ServerMessage>> execute(
    Client client, ConnectionContext context, String sql, PreparedIdentifier identifier, boolean deprecateEof, int fetchSize, List<Binding> bindings
) {
    switch (bindings.size()) {
        case 1: // Most case.
            return Flux.defer(() -> execute0(client, context, sql, identifier, deprecateEof, bindings.get(0), fetchSize)
                .windowUntil(RESULT_DONE));
        case 0:
            return Flux.empty();
        default:
            Iterator<Binding> iterator = bindings.iterator();
            EmitterProcessor<Binding> processor = EmitterProcessor.create(1, true);
            Runnable complete = () -> {
                if (processor.isCancelled() || processor.isTerminated()) {
                    return;
                }

                try {
                    if (iterator.hasNext()) {
                        if (identifier.isClosed()) {
                            // User cancelled fetching, discard subsequent bindings.
                            Binding.clearSubsequent(iterator);
                            processor.onComplete();
                        } else {
                            processor.onNext(iterator.next());
                        }
                    } else {
                        processor.onComplete();
                    }
                } catch (Throwable e) {
                    processor.onError(e);
                }
            };

            processor.onNext(iterator.next());

            // One binding may be leak when a emitted Result has been ignored, but Result should never be ignored.
            // Subsequent bindings will auto-clear if subscribing has been cancelled.
            return processor.concatMap(it -> execute0(client, context, sql, identifier, deprecateEof, it, fetchSize).doOnComplete(complete))
                .doOnCancel(() -> Binding.clearSubsequent(iterator))
                .doOnError(ignored -> Binding.clearSubsequent(iterator))
                .windowUntil(RESULT_DONE);
    }
}
 
Example 16
@Override
public Flux<String> testMethod13() {
	return Flux
			.defer(() -> Flux.error(new RuntimeException("test exception 13")));
}
 
Example 17
Source Project: Moss   File: ConcurrentMapEventStore.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public Flux<InstanceEvent> findAll() {
    return Flux.defer(() -> Flux.fromIterable(eventLog.values())
                                .flatMapIterable(Function.identity())
                                .sort(byTimestampAndIdAndVersion));
}
 
Example 18
Source Project: r2dbc-mysql   File: BlobCodec.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public Flux<ByteBuf> publishBinary() {
    return Flux.defer(() -> {
        Blob blob = this.blob.getAndSet(null);

        if (blob == null) {
            return Flux.error(new IllegalStateException("Blob has written, can not write twice"));
        }

        // Must have defaultIfEmpty, try Mono.fromCallable(() -> null).flux().collectList()
        return Flux.from(blob.stream())
            .collectList()
            .defaultIfEmpty(Collections.emptyList())
            .flatMapIterable(list -> {
                if (list.isEmpty()) {
                    // It is zero of var int, not terminal.
                    return Collections.singletonList(allocator.buffer(Byte.BYTES).writeByte(0));
                }

                long bytes = 0;
                List<ByteBuf> buffers = new ArrayList<>();
                ByteBuf lastBuf = allocator.buffer();

                try {
                    ByteBuf firstBuf = lastBuf;

                    buffers.add(firstBuf);
                    VarIntUtils.reserveVarInt(firstBuf);

                    for (ByteBuffer src : list) {
                        if (src.hasRemaining()) {
                            int size = src.remaining();
                            bytes += size;

                            // size + lastBuf.readableBytes() > MAX_MERGE
                            if (size > MAX_MERGE - lastBuf.readableBytes()) {
                                lastBuf = allocator.buffer();
                                buffers.add(lastBuf);
                            }

                            lastBuf.writeBytes(src);
                        }
                    }

                    VarIntUtils.setReservedVarInt(firstBuf, bytes);

                    return toList(buffers);
                } catch (Throwable e) {
                    releaseAll(buffers, lastBuf);
                    throw e;
                }
            });
    });
}
 
Example 19
private Flux<DataBuffer> getRegionSuffix(DataBufferFactory bufferFactory, String boundaryString) {
	byte[] endBoundary = getAsciiBytes("\r\n--" + boundaryString + "--");
	return Flux.defer(() -> Flux.just(
			bufferFactory.allocateBuffer(endBoundary.length).write(endBoundary)));
}
 
Example 20
Source Project: r2dbc-mysql   File: QueryFlow.java    License: Apache License 2.0 2 votes vote down vote up
/**
 * Execute a simple compound query and return its results. Query execution terminates with
 * each {@link CompleteMessage} or a {@link ErrorMessage}. The {@link ErrorMessage} will
 * emit an exception.
 *
 * @param client the {@link Client} to exchange messages with.
 * @param sql    the query to execute, can be contains multi-statements.
 * @return the messages received in response to this exchange, and will be completed by {@link CompleteMessage} when it is the last.
 */
static Flux<Flux<ServerMessage>> execute(Client client, String sql) {
    return Flux.defer(() -> execute0(client, sql).windowUntil(RESULT_DONE));
}