MCPcopy Create free account
hub / github.com/Permify/permify / Write

Method Write

internal/storage/postgres/data_writer.go:42–83  ·  view source on GitHub ↗

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,
)

Source from the content-addressed store, hash-verified

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.
42func (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.

Callers

nothing calls this directly

Implementers 6

dataClientpkg/pb/base/v1/service_grpc.pb.go
UnimplementedDataServerpkg/pb/base/v1/service_grpc.pb.go
NoopDataWriterinternal/storage/storage.go
DataWriterinternal/storage/postgres/data_writer.
DataWriterinternal/storage/memory/data_writer.go
DataServerinternal/servers/data_server.go

Calls 10

writeMethod · 0.95
WaitWithBackoffFunction · 0.92
HandleErrorFunction · 0.92
StartMethod · 0.80
GetMaxRetriesMethod · 0.80
GetMaxDataPerWriteMethod · 0.80
StringMethod · 0.65
GetTuplesMethod · 0.45
GetAttributesMethod · 0.45

Tested by

no test coverage detected