Write method writes a collection of tuples and attributes to the database for a specific tenant. It returns an EncodedSnapToken upon successful write or an error if the write fails.
( ctx context.Context, tenantID string, tupleCollection *database.TupleCollection, attributeCollection *database.AttributeCollection, )
| 40 | // Write method writes a collection of tuples and attributes to the database for a specific tenant. |
| 41 | // It returns an EncodedSnapToken upon successful write or an error if the write fails. |
| 42 | func (w *DataWriter) Write( |
| 43 | ctx context.Context, |
| 44 | tenantID string, |
| 45 | tupleCollection *database.TupleCollection, |
| 46 | attributeCollection *database.AttributeCollection, |
| 47 | ) (token token.EncodedSnapToken, err error) { |
| 48 | // Start a new tracing span for this operation. |
| 49 | ctx, span := internal.Tracer.Start(ctx, "data-writer.write") |
| 50 | defer span.End() // Ensure that the span is ended when the function returns. |
| 51 | |
| 52 | // Log the start of a data write operation. |
| 53 | slog.DebugContext(ctx, "writing data for tenant_id", slog.String("tenant_id", tenantID), "max retries", slog.Any("max_retries", w.database.GetMaxRetries())) |
| 54 | // Validate data size |
| 55 | // Check if the total number of tuples and attributes exceeds the maximum allowed per write. |
| 56 | if len(tupleCollection.GetTuples())+len(attributeCollection.GetAttributes()) > w.database.GetMaxDataPerWrite() { |
| 57 | return nil, errors.New(base.ErrorCode_ERROR_CODE_MAX_DATA_PER_WRITE_EXCEEDED.String()) |
| 58 | } |
| 59 | |
| 60 | // Retry loop for handling transient errors like serialization issues. |
| 61 | for i := 0; i <= w.database.GetMaxRetries(); i++ { |
| 62 | // Attempt to write the data to the database. |
| 63 | tkn, err := w.write(ctx, tenantID, tupleCollection, attributeCollection) |
| 64 | if err != nil { |
| 65 | // Check if the error is due to serialization, and if so, retry. |
| 66 | if utils.IsSerializationRelatedError(err) || pgconn.SafeToRetry(err) { |
| 67 | slog.WarnContext(ctx, "serialization error occurred", slog.String("tenant_id", tenantID), slog.Int("retry", i)) |
| 68 | utils.WaitWithBackoff(ctx, tenantID, i) |
| 69 | continue // Retry the operation. |
| 70 | } |
| 71 | // If the error is not serialization-related, handle it and return. |
| 72 | return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_DATASTORE) |
| 73 | } |
| 74 | // If to write is successful, return the token. |
| 75 | return tkn, nil |
| 76 | } |
| 77 | |
| 78 | // Log an error if the operation failed after reaching the maximum number of retries. |
| 79 | slog.ErrorContext(ctx, "max retries reached", slog.Any("error", errors.New(base.ErrorCode_ERROR_CODE_ERROR_MAX_RETRIES.String()))) |
| 80 | // Max retries exceeded |
| 81 | // Return an error indicating that the maximum number of retries has been reached. |
| 82 | return nil, errors.New(base.ErrorCode_ERROR_CODE_ERROR_MAX_RETRIES.String()) |
| 83 | } |
| 84 | |
| 85 | // Delete method removes data from the database based on the provided tuple and attribute filters. |
| 86 | // It returns an EncodedSnapToken upon successful deletion or an error if the deletion fails. |
nothing calls this directly
no test coverage detected