You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fory.apache.org by ch...@apache.org on 2026/09/07 16:56:30 UTC
(fory-site) branch main updated: 🔄 synced local 'docs/object-serialization/' with remote 'docs/object-serialization/'
This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new fe9715cbcff 🔄 synced local 'docs/object-serialization/' with remote 'docs/object-serialization/'
fe9715cbcff is described below
commit fe9715cbcff5050170f82d1d75e9eae53cacb2d7
Author: chaokunyang <sh...@gmail.com>
AuthorDate: Mon Sep 7 16:56:26 2026 +0000
🔄 synced local 'docs/object-serialization/' with remote 'docs/object-serialization/'
---
docs/object-serialization/go/configuration.md | 2 +-
docs/object-serialization/go/thread-safety.md | 75 +++++++++++++--------------
2 files changed, 36 insertions(+), 41 deletions(-)
diff --git a/docs/object-serialization/go/configuration.md b/docs/object-serialization/go/configuration.md
index 8f59db06e21..50850328dd6 100644
--- a/docs/object-serialization/go/configuration.md
+++ b/docs/object-serialization/go/configuration.md
@@ -241,7 +241,7 @@ go func() {
The thread-safe wrapper:
-- Uses `sync.Pool` internally for efficient instance reuse
+- Creates instances as needed and reuses them across goroutines
- Automatically copies serialized data before returning
- Accepts the same configuration options as `fory.New()`
diff --git a/docs/object-serialization/go/thread-safety.md b/docs/object-serialization/go/thread-safety.md
index 89b53676675..a9ed08dfc9a 100644
--- a/docs/object-serialization/go/thread-safety.md
+++ b/docs/object-serialization/go/thread-safety.md
@@ -66,32 +66,11 @@ go func() {
}()
```
-### How It Works
-
-The thread-safe wrapper uses `sync.Pool`:
-
-1. **Acquire**: Gets a Fory instance from the pool
-2. **Use**: Performs serialization/deserialization
-3. **Copy**: Copies result data (buffer will be reused)
-4. **Release**: Returns instance to pool
-
-```go
-// Simplified implementation
-func (f *Fory) Serialize(v any) ([]byte, error) {
- fory := f.pool.Get().(*fory.Fory)
- defer f.pool.Put(fory)
-
- data, err := fory.Serialize(v)
- if err != nil {
- return nil, err
- }
-
- // Copy because underlying buffer will be reused
- result := make([]byte, len(data))
- copy(result, data)
- return result, nil
-}
-```
+The wrapper creates instances as needed and reuses them across goroutines.
+Each operation exclusively borrows one instance and returns it afterward.
+Registered types remain available when garbage collection reclaims cached
+instances. Serialized output is copied before returning, so callers can retain
+it safely.
### API
@@ -114,32 +93,48 @@ err = threadsafe.Unmarshal(data, &target)
## Type Registration
-Type registration should be done before concurrent use:
+Register all types before the first serialization or deserialization operation. The
+first operation permanently freezes the wrapper's registrations, even if that
+operation fails. A later registration attempt returns an error.
```go
f := threadsafe.New()
-// Register types BEFORE concurrent access
-f.RegisterStruct(User{}, 1)
-f.RegisterStruct(Order{}, 2)
+if err := f.RegisterStruct(User{}, 1); err != nil {
+ panic(err)
+}
+if err := f.RegisterStruct(Order{}, 2); err != nil {
+ panic(err)
+}
-// Now safe to use concurrently
+// All concurrent operations use the registered types.
go func() {
- f.Serialize(&User{ID: 1})
+ data, err := f.Serialize(&User{ID: 1})
+ // Use data and handle err.
+ _, _ = data, err
}()
```
-### Thread-Safe Registration
+`RegisterStructByName`, `RegisterEnum`, and `RegisterEnumByName` are also
+available directly on the wrapper. Every registered type is available to all
+concurrent operations and remains registered across garbage collections.
-The thread-safe wrapper handles registration safely:
+For custom per-instance initialization, use `NewWithFactory`:
```go
-// Safe: Registration is synchronized
-f := threadsafe.New()
-f.RegisterStruct(User{}, 1) // Thread-safe
+f := threadsafe.NewWithFactory(func() *fory.Fory {
+ inner := fory.New()
+ if err := inner.RegisterExtension(CustomType{}, 100, newCustomSerializer()); err != nil {
+ panic(err)
+ }
+ return inner
+})
```
-However, for best performance, register all types at startup before concurrent use.
+The factory may be called concurrently as additional instances are needed. It
+must return a fresh, identically configured instance on every call, with
+registrations completed before returning. Create stateful custom serializers
+separately for each instance.
## Zero-Copy Considerations
@@ -331,11 +326,11 @@ go func() {
}()
```
-**Fix**: Register all types before concurrent use.
+**Fix**: Register all types before the first serialization or deserialization.
## Best Practices
-1. **Register types at startup**: Before any concurrent operations
+1. **Register types at startup**: Before the first serialization or deserialization
2. **Clone data if keeping references**: With non-thread-safe instance
3. **Use per-worker instances for hot paths**: Eliminates pool contention
4. **Profile before optimizing**: Thread-safe overhead may be negligible
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@fory.apache.org
For additional commands, e-mail: commits-help@fory.apache.org