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

The following examples show how to use reactor.core.publisher.Flux#defer() . 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 File: DashBoardSubscriptionProvider.java    From jetlinks-community with Apache License 2.0 6 votes vote down vote up
@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 2
Source File: QueryFlow.java    From r2dbc-mysql with 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 3
Source File: PrepareSimpleStatement.java    From r2dbc-mysql with Apache License 2.0 5 votes vote down vote up
@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 4
Source File: PrepareSimpleStatement.java    From r2dbc-mysql with Apache License 2.0 5 votes vote down vote up
@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
Source File: DiscoveryService.java    From Learning-Path-Spring-5-End-to-End-Programming with MIT License 5 votes vote down vote up
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 6
Source File: DiscoveryService.java    From Learning-Path-Spring-5-End-to-End-Programming with MIT License 5 votes vote down vote up
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 7
Source File: ParametrizedStatementSupport.java    From r2dbc-mysql with Apache License 2.0 5 votes vote down vote up
@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 8
Source File: GrpcRelocationReplicatorEventStream.java    From titus-control-plane with Apache License 2.0 5 votes vote down vote up
@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 9
Source File: MySqlResult.java    From r2dbc-mysql with 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 10
Source File: KubeClusterMembershipConnector.java    From titus-control-plane with Apache License 2.0 5 votes vote down vote up
@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 11
Source File: ParametrizedStatementSupport.java    From r2dbc-mysql with Apache License 2.0 5 votes vote down vote up
@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 12
Source File: QueryFlow.java    From r2dbc-mysql with 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 13
Source File: BufferingFlux.java    From micrometer with 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 14
Source File: SleuthSpanCreatorAspectFluxTests.java    From spring-cloud-sleuth with Apache License 2.0 4 votes vote down vote up
@Override
public Flux<String> testMethod13() {
	return Flux
			.defer(() -> Flux.error(new RuntimeException("test exception 13")));
}
 
Example 15
Source File: FluxRestApplicationTests.java    From spring-cloud-function with Apache License 2.0 4 votes vote down vote up
@GetMapping("/timeout")
public Flux<?> timeout() {
	return Flux.defer(() -> Flux.<String>create(emitter -> {
		emitter.next("foo");
	}).timeout(Duration.ofMillis(100L), Flux.empty()));
}
 
Example 16
Source File: ClobCodec.java    From r2dbc-mysql with 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 17
Source File: ConcurrentMapEventStore.java    From Moss with 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 File: BlobCodec.java    From r2dbc-mysql with 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
Source File: ResourceRegionEncoder.java    From java-technology-stack with MIT License 4 votes vote down vote up
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 File: QueryFlow.java    From r2dbc-mysql with 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));
}