Передать контекст из одного потока / моно в другой - PullRequest
0 голосов
/ 05 июля 2018

Интересные вещи происходят внутри пакета webflux. Однако мое путешествие по источнику не решило следующий вопрос.

Допустим, у меня есть следующий моно (или поток):

Mono hello = Mono.empty()
            .subscriberContext(ctx -> ctx.put("message", "hello"));

Я использую аналогичную конструкцию в веб-фильтре, чтобы обогатить конвейер пользовательскими и пользовательскими данными. Затем в контроллере используется такая конструкция:

Mono world = Mono.subscriberContext()
            .map(ctx -> (String)ctx.get("message"));

Контекст привет моно заполнен в мире моно. Я попытался выяснить, как это сделать, также для целей модульного тестирования.

В конце концов, это остается загадкой. Я попытался сделать это с помощью обычных методов, доступных для обоих объектов mono / flux, но мне не удалось сделать контекст hello доступным для мира mono. Как вы можете объединить потоки и моно и передать контекст по пути к вышестоящим операторам?

Ответы [ 2 ]

0 голосов
/ 14 июля 2018

Вы хотите сделать пару вещей:

1.) Публикация контекста подписчика

mono.subscriberContext({ Context context ->
    context.put("key", "value")
})

2.) Подписаться / получить доступ к контексту подписчика

mono.flatMap({ def r ->
    return Mono.subscriberContext().map({ Context context ->
        context.get("key")
        context.get("keyOrMapOrStateObject").put("someKey", "someData")
        return r
    })
})

3.) Потенциально передать данные из одного события в последующее событие

mono.flatMap({ def r ->
    return Mono.subscriberContext().map({ Context context ->
        def someData = context.get("keyOrMapOrStateObject").get("someKey")
        return r
    })
})

Все вместе это будет выглядеть примерно так: (это отличный синтаксис)

mono.flatMap({ def r ->
    return Mono.subscriberContext().map({ Context context ->
        context.get("key")
        context.get("keyOrMapOrStateObject").put("someKey", "someData")
        return r
    })
}).flatMap({ def r ->
    return Mono.subscriberContext().map({ Context context ->
        def someData = context.get("keyOrMapOrStateObject").get("someKey")
        return r
    })
}).subscriberContext({ Context context ->
    context.put("key", "value")
    context.put("keyOrMapOrStateObject", new HashMap())
})

Это грубый набросок - не готов "как есть", но он должен помочь вам понять шаблон.

Удачи!

0 голосов
/ 05 июля 2018

WebFlux берет ваше world Mono и строит на его основе реактивную цепочку с HTTP-запросом в реактор-нетто в качестве основного источника. WebFilter являются частью конструкции цепи, поэтому они могут обогатить Context всей цепи.

IIRC Mono.subscriberContext() будет использоваться внутри flatMap, что делает главную последовательность Context доступной для его внутренних, так что он может видеть Context из hello.

...