Skip to content

Commit c68b5fe

Browse files
committed
sr/service: Add topic metadata polling loop after creation
Signed-off-by: Oren Leiman <oren.leiman@redpanda.com>
1 parent 45e3f32 commit c68b5fe

1 file changed

Lines changed: 42 additions & 6 deletions

File tree

src/v/pandaproxy/schema_registry/service.cc

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "kafka/client/exceptions.h"
2222
#include "kafka/data/rpc/deps.h"
2323
#include "kafka/protocol/errors.h"
24+
#include "kafka/protocol/exceptions.h"
2425
#include "kafka/protocol/list_offset.h"
2526
#include "kafka/server/handlers/topics/types.h"
2627
#include "model/fundamental.h"
@@ -29,6 +30,7 @@
2930
#include "pandaproxy/logger.h"
3031
#include "pandaproxy/schema_registry/auth.h"
3132
#include "pandaproxy/schema_registry/configuration.h"
33+
#include "pandaproxy/schema_registry/exceptions.h"
3234
#include "pandaproxy/schema_registry/handlers.h"
3335
#include "pandaproxy/schema_registry/storage.h"
3436
#include "pandaproxy/schema_registry/types.h"
@@ -43,6 +45,8 @@
4345

4446
#include <seastar/core/coroutine.hh>
4547
#include <seastar/core/future-util.hh>
48+
#include <seastar/core/sleep.hh>
49+
#include <seastar/coroutine/parallel_for_each.hh>
4650
#include <seastar/http/api_docs.hh>
4751
#include <seastar/util/log.hh>
4852
#include <seastar/util/noncopyable_function.hh>
@@ -381,12 +385,44 @@ ss::future<> service::do_start() {
381385
std::current_exception());
382386
throw;
383387
}
384-
co_await container().invoke_on_all(_ctx.smp_sg, [](service& s) {
385-
s._is_started = true;
386-
return ss::this_shard_id() == seq_writer::reader_shard
387-
? s.fetch_internal_topic()
388-
: ss::now();
389-
});
388+
co_await container().invoke_on_all(
389+
_ctx.smp_sg, [](this auto, service& s) -> ss::future<> {
390+
s._is_started = true;
391+
if (ss::this_shard_id() != seq_writer::reader_shard) {
392+
co_return;
393+
}
394+
395+
// create_internal_topic returns once the controller commits
396+
// the topic, but the metadata cache is updated asynchronously.
397+
// Transient errors during this window — topic not yet visible,
398+
// leader not yet elected — are retried here. The kafka client
399+
// transport surfaces these as SR exceptions, while the RPC
400+
// transport surfaces them as kafka::exceptions. Both use
401+
// unknown_server_error.
402+
for (int attempts = 0;; ++attempts) {
403+
auto fut = co_await ss::coroutine::as_future(
404+
s.fetch_internal_topic());
405+
if (!fut.failed()) {
406+
co_return;
407+
}
408+
auto eptr = fut.get_exception();
409+
bool retriable = false;
410+
try {
411+
std::rethrow_exception(eptr);
412+
} catch (const kafka::exception_base& e) {
413+
retriable = e.error == kafka::error_code::unknown_server_error
414+
&& attempts < 10;
415+
} catch (const exception& e) {
416+
retriable = e.code()
417+
== kafka::error_code::unknown_server_error
418+
&& attempts < 10;
419+
}
420+
if (!retriable) {
421+
std::rethrow_exception(eptr);
422+
}
423+
co_await ss::sleep(std::chrono::milliseconds(100));
424+
}
425+
});
390426
}
391427

392428
ss::future<> create_acls(cluster::security_frontend& security_fe) {

0 commit comments

Comments
 (0)