-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[fix][broker] Fix schema does not replicate successfully #17049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0a753d7
691fd25
a756613
a995883
ee1563f
221e74b
312b4d5
98eb1d4
0e3d62b
cdd89cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -62,6 +62,7 @@ | |||
| import org.apache.bookkeeper.mledger.impl.ManagedCursorImpl.State; | ||||
| import org.apache.bookkeeper.mledger.impl.ManagedLedgerFactoryImpl; | ||||
| import org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl; | ||||
| import org.apache.bookkeeper.mledger.impl.PositionImpl; | ||||
| import org.apache.pulsar.broker.BrokerTestUtil; | ||||
| import org.apache.pulsar.broker.PulsarService; | ||||
| import org.apache.pulsar.broker.service.BrokerServiceException.NamingException; | ||||
|
|
@@ -70,6 +71,7 @@ | |||
| import org.apache.pulsar.client.admin.PulsarAdmin; | ||||
| import org.apache.pulsar.client.api.Consumer; | ||||
| import org.apache.pulsar.client.api.Message; | ||||
| import org.apache.pulsar.client.api.MessageId; | ||||
| import org.apache.pulsar.client.api.MessageRoutingMode; | ||||
| import org.apache.pulsar.client.api.Producer; | ||||
| import org.apache.pulsar.client.api.PulsarClient; | ||||
|
|
@@ -78,6 +80,7 @@ | |||
| import org.apache.pulsar.client.api.Schema; | ||||
| import org.apache.pulsar.client.api.SubscriptionType; | ||||
| import org.apache.pulsar.client.api.TypedMessageBuilder; | ||||
| import org.apache.pulsar.client.impl.MessageIdImpl; | ||||
| import org.apache.pulsar.client.impl.ProducerImpl; | ||||
| import org.apache.pulsar.client.impl.PulsarClientImpl; | ||||
| import org.apache.pulsar.client.impl.conf.ProducerConfigurationData; | ||||
|
|
@@ -392,19 +395,24 @@ public void testReplicationWithSchema() throws Exception { | |||
| final String subName = "my-sub"; | ||||
|
|
||||
| @Cleanup | ||||
| Producer<Schemas.PersonOne> producer1 = client1.newProducer(Schema.AVRO(Schemas.PersonOne.class)) | ||||
| .topic(topic.toString()) | ||||
| .create(); | ||||
| @Cleanup | ||||
| Producer<Schemas.PersonOne> producer2 = client2.newProducer(Schema.AVRO(Schemas.PersonOne.class)) | ||||
| .topic(topic.toString()) | ||||
| .create(); | ||||
| @Cleanup | ||||
| Producer<Schemas.PersonOne> producer3 = client3.newProducer(Schema.AVRO(Schemas.PersonOne.class)) | ||||
| Producer<Schemas.PersonOne> producer = client1.newProducer(Schema.AVRO(Schemas.PersonOne.class)) | ||||
| .topic(topic.toString()) | ||||
| .create(); | ||||
|
|
||||
| List<Producer<Schemas.PersonOne>> producers = Lists.newArrayList(producer1, producer2, producer3); | ||||
| admin1.topics().createSubscription(topic.toString(), subName, MessageId.earliest); | ||||
| admin2.topics().createSubscription(topic.toString(), subName, MessageId.earliest); | ||||
| admin3.topics().createSubscription(topic.toString(), subName, MessageId.earliest); | ||||
|
|
||||
|
|
||||
| for (int i = 0; i < 10; i++) { | ||||
| producer.send(new Schemas.PersonOne(i)); | ||||
| } | ||||
|
|
||||
| Awaitility.await().untilAsserted(() -> { | ||||
| assertTrue(admin1.topics().getInternalStats(topic.toString()).schemaLedgers.size() > 0); | ||||
| assertTrue(admin2.topics().getInternalStats(topic.toString()).schemaLedgers.size() > 0); | ||||
| assertTrue(admin3.topics().getInternalStats(topic.toString()).schemaLedgers.size() > 0); | ||||
| }); | ||||
|
|
||||
| @Cleanup | ||||
| Consumer<Schemas.PersonOne> consumer1 = client1.newConsumer(Schema.AVRO(Schemas.PersonOne.class)) | ||||
|
|
@@ -424,8 +432,7 @@ public void testReplicationWithSchema() throws Exception { | |||
| .subscriptionName(subName) | ||||
| .subscribe(); | ||||
|
|
||||
| for (int i = 0; i < 3; i++) { | ||||
| producers.get(i).send(new Schemas.PersonOne(i)); | ||||
| for (int i = 0; i < 10; i++) { | ||||
| Message<Schemas.PersonOne> msg1 = consumer1.receive(); | ||||
| Message<Schemas.PersonOne> msg2 = consumer2.receive(); | ||||
| Message<Schemas.PersonOne> msg3 = consumer3.receive(); | ||||
|
|
@@ -1395,15 +1402,21 @@ public void testReplicatorWithFailedAck() throws Exception { | |||
|
|
||||
| PersistentTopic topic = (PersistentTopic) pulsar1.getBrokerService().getTopic(dest.toString(), false) | ||||
| .getNow(null).get(); | ||||
| MessageIdImpl lastMessageId = (MessageIdImpl) topic.getLastMessageId().get(); | ||||
| Position lastPosition = PositionImpl.get(lastMessageId.getLedgerId(), lastMessageId.getEntryId()); | ||||
| ConcurrentOpenHashMap<String, Replicator> replicators = topic.getReplicators(); | ||||
| PersistentReplicator replicator = (PersistentReplicator) replicators.get("r2"); | ||||
|
|
||||
| Awaitility.await().timeout(50, TimeUnit.SECONDS) | ||||
| Awaitility.await().pollInterval(1, TimeUnit.SECONDS).timeout(30, TimeUnit.SECONDS) | ||||
| .untilAsserted(() -> assertEquals(org.apache.pulsar.broker.service.AbstractReplicator.State.Started, | ||||
| replicator.getState())); | ||||
|
|
||||
| assertEquals(replicator.getState(), org.apache.pulsar.broker.service.AbstractReplicator.State.Started); | ||||
| ManagedCursorImpl cursor = (ManagedCursorImpl) replicator.getCursor(); | ||||
|
|
||||
| // Make sure all the data has replicated to the remote cluster before close the cursor. | ||||
| Awaitility.await().untilAsserted(() -> assertEquals(cursor.getMarkDeletedPosition(), lastPosition)); | ||||
|
|
||||
| cursor.setState(State.Closed); | ||||
|
|
||||
| Field field = ManagedCursorImpl.class.getDeclaredField("state"); | ||||
|
|
@@ -1412,22 +1425,16 @@ public void testReplicatorWithFailedAck() throws Exception { | |||
|
|
||||
| producer1.produce(10); | ||||
|
|
||||
| Position deletedPos = cursor.getMarkDeletedPosition(); | ||||
| Position readPos = cursor.getReadPosition(); | ||||
|
|
||||
| Awaitility.await().timeout(30, TimeUnit.SECONDS).until( | ||||
| () -> cursor.getMarkDeletedPosition().getEntryId() != (cursor.getReadPosition().getEntryId() - 1)); | ||||
|
|
||||
| assertNotEquals((readPos.getEntryId() - 1), deletedPos.getEntryId()); | ||||
|
Comment on lines
-1415
to
-1421
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed here because the producer might be closed with pending messages. After the cursor change to the close state, the producer will also be closed after a read entries failure. So that all the pending messages will fail with the Line 425 in 9f40cc1
This will make the check failed. |
||||
| // The cursor is closed, so the mark delete position will not move forward. | ||||
| assertEquals(cursor.getMarkDeletedPosition(), lastPosition); | ||||
|
|
||||
| field.set(cursor, State.Open); | ||||
|
|
||||
| Awaitility.await().timeout(30, TimeUnit.SECONDS).until( | ||||
| () -> cursor.getMarkDeletedPosition().getEntryId() == (cursor.getReadPosition().getEntryId() - 1)); | ||||
|
|
||||
| deletedPos = cursor.getMarkDeletedPosition(); | ||||
| readPos = cursor.getReadPosition(); | ||||
| assertEquals((readPos.getEntryId() - 1), deletedPos.getEntryId()); | ||||
| () -> { | ||||
| log.info("++++++++++++ {}, {}", cursor.getMarkDeletedPosition(), cursor.getReadPosition()); | ||||
| return cursor.getMarkDeletedPosition().getEntryId() == (cursor.getReadPosition().getEntryId() - 1); | ||||
| }); | ||||
| } | ||||
|
|
||||
| private static final Logger log = LoggerFactory.getLogger(ReplicatorTest.class); | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@codelipenghui do you remember why this was needed? I added #17943 to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motivation is here #17152
Although I think it's safe to add it back