|
38 | 38 | errNoAllowedCodecs = xerrors.Wrap(errors.New("ydb: no allowed codecs for write to topic"))
|
39 | 39 | errLargeMessage = xerrors.Wrap(errors.New("ydb: message uncompressed size more, then limit"))
|
40 | 40 | PublicErrQueueIsFull = xerrors.Wrap(errors.New("ydb: queue is full"))
|
| 41 | + errDiffetentTransactions = xerrors.Wrap(errors.New("ydb: internal writer has messages from different trasactions. It is internal logic error, write issue please: https://github.com/ydb-platform/ydb-go-sdk/issues/new?assignees=&labels=bug&projects=&template=01_BUG_REPORT.md&title=bug%3A+")) |
41 | 42 |
|
42 | 43 | // errProducerIDNotEqualMessageGroupID is temporary
|
43 | 44 | // WithMessageGroupID is optional parameter because it allowed to be skipped by protocol.
|
@@ -73,14 +74,14 @@ func (cfg *WriterReconnectorConfig) validate() error {
|
73 | 74 | return nil
|
74 | 75 | }
|
75 | 76 |
|
76 |
| -func newWriterReconnectorConfig(options ...PublicWriterOption) WriterReconnectorConfig { |
| 77 | +func NewWriterReconnectorConfig(options ...PublicWriterOption) WriterReconnectorConfig { |
77 | 78 | cfg := WriterReconnectorConfig{
|
78 | 79 | WritersCommonConfig: WritersCommonConfig{
|
79 | 80 | cred: credentials.NewAnonymousCredentials(),
|
80 | 81 | credUpdateInterval: time.Hour,
|
81 | 82 | clock: clockwork.NewRealClock(),
|
82 | 83 | compressorCount: runtime.NumCPU(),
|
83 |
| - tracer: &trace.Topic{}, |
| 84 | + Tracer: &trace.Topic{}, |
84 | 85 | },
|
85 | 86 | AutoSetSeqNo: true,
|
86 | 87 | AutoSetCreatedTime: true,
|
@@ -119,25 +120,29 @@ type WriterReconnector struct {
|
119 | 120 | background background.Worker
|
120 | 121 | retrySettings topic.RetrySettings
|
121 | 122 | writerInstanceID string
|
122 |
| - sessionID string |
123 | 123 | semaphore *semaphore.Weighted
|
124 | 124 | firstInitResponseProcessedChan empty.Chan
|
125 | 125 | lastSeqNo int64
|
126 | 126 | encodersMap *EncoderMap
|
127 | 127 | initDoneCh empty.Chan
|
128 | 128 | initInfo InitialInfo
|
129 | 129 | m xsync.RWMutex
|
| 130 | + sessionID string |
130 | 131 | firstConnectionHandled atomic.Bool
|
131 | 132 | initDone bool
|
132 | 133 | }
|
133 | 134 |
|
134 |
| -func newWriterReconnector( |
135 |
| - cfg WriterReconnectorConfig, //nolint:gocritic |
136 |
| -) *WriterReconnector { |
| 135 | +func NewWriterReconnector( |
| 136 | + cfg WriterReconnectorConfig, |
| 137 | +) (*WriterReconnector, error) { |
| 138 | + if err := cfg.validate(); err != nil { |
| 139 | + return nil, err |
| 140 | + } |
| 141 | + |
137 | 142 | res := newWriterReconnectorStopped(cfg)
|
138 | 143 | res.start()
|
139 | 144 |
|
140 |
| - return res |
| 145 | + return res, nil |
141 | 146 | }
|
142 | 147 |
|
143 | 148 | func newWriterReconnectorStopped(
|
@@ -313,7 +318,7 @@ func (w *WriterReconnector) createMessagesWithContent(messages []PublicMessage)
|
313 | 318 | sessionID = w.sessionID
|
314 | 319 | })
|
315 | 320 | onCompressDone := trace.TopicOnWriterCompressMessages(
|
316 |
| - w.cfg.tracer, |
| 321 | + w.cfg.Tracer, |
317 | 322 | w.writerInstanceID,
|
318 | 323 | sessionID,
|
319 | 324 | w.cfg.forceCodec.ToInt32(),
|
@@ -354,7 +359,7 @@ func (w *WriterReconnector) Close(ctx context.Context) error {
|
354 | 359 | }
|
355 | 360 |
|
356 | 361 | func (w *WriterReconnector) close(ctx context.Context, reason error) (resErr error) {
|
357 |
| - onDone := trace.TopicOnWriterClose(w.cfg.tracer, w.writerInstanceID, reason) |
| 362 | + onDone := trace.TopicOnWriterClose(w.cfg.Tracer, w.writerInstanceID, reason) |
358 | 363 | defer func() {
|
359 | 364 | onDone(resErr)
|
360 | 365 | }()
|
@@ -461,7 +466,7 @@ func (w *WriterReconnector) startWriteStream(ctx, streamCtx context.Context, att
|
461 | 466 | err error,
|
462 | 467 | ) {
|
463 | 468 | traceOnDone := trace.TopicOnWriterReconnect(
|
464 |
| - w.cfg.tracer, |
| 469 | + w.cfg.Tracer, |
465 | 470 | w.writerInstanceID,
|
466 | 471 | w.cfg.topic,
|
467 | 472 | w.cfg.producerID,
|
@@ -625,6 +630,13 @@ func (w *WriterReconnector) createWriterStreamConfig(stream RawTopicWriterStream
|
625 | 630 | return cfg
|
626 | 631 | }
|
627 | 632 |
|
| 633 | +func (w *WriterReconnector) GetSessionID() (sessionID string) { |
| 634 | + w.m.WithLock(func() { |
| 635 | + sessionID = w.sessionID |
| 636 | + }) |
| 637 | + return sessionID |
| 638 | +} |
| 639 | + |
628 | 640 | func sendMessagesToStream(
|
629 | 641 | stream RawTopicWriterStream,
|
630 | 642 | targetCodec rawtopiccommon.Codec,
|
@@ -684,6 +696,17 @@ func createWriteRequest(messages []messageWithDataContent, targetCodec rawtopicc
|
684 | 696 | res rawtopicwriter.WriteRequest,
|
685 | 697 | err error,
|
686 | 698 | ) {
|
| 699 | + for i := 1; i < len(messages); i++ { |
| 700 | + if messages[i-1].tx != messages[i].tx { |
| 701 | + return res, xerrors.WithStackTrace(errDiffetentTransactions) |
| 702 | + } |
| 703 | + } |
| 704 | + |
| 705 | + if len(messages) > 0 { |
| 706 | + res.Tx.ID = messages[0].tx.ID() |
| 707 | + res.Tx.Session = messages[0].tx.SessionID() |
| 708 | + } |
| 709 | + |
687 | 710 | res.Codec = targetCodec
|
688 | 711 | res.Messages = make([]rawtopicwriter.MessageData, len(messages))
|
689 | 712 | for i := range messages {
|
|
0 commit comments