Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ public AbstractByteBuf encode(final Object object, final Map<String, String> con
if (object == null) {
throw buildSerializeError("Unsupported null message!");
}
// Set the context classloader so Fury can resolve classes correctly.
// We intentionally do NOT call clearClassLoader() afterwards; that would destroy the
// thread-local Fury instance on every call, causing a new instance to be created each
// time and generating massive GC pressure under high throughput.
// setClassLoader() already handles classloader changes (e.g. in OSGi/hot-deploy
// environments) by creating a new Fury instance when the classloader differs.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
fury.setClassLoader(contextClassLoader);
Expand All @@ -126,8 +132,6 @@ public AbstractByteBuf encode(final Object object, final Map<String, String> con
}
} catch (Exception e) {
throw buildSerializeError(e.getMessage(), e);
} finally {
fury.clearClassLoader(contextClassLoader);
}
}

Expand All @@ -137,6 +141,7 @@ public Object decode(final AbstractByteBuf data, final Class clazz, final Map<St
if (data.readableBytes() <= 0 || clazz == null) {
throw buildDeserializeError("Deserialized array is empty.");
}
// See encode() for the rationale of not calling clearClassLoader() here.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
fury.setClassLoader(contextClassLoader);
Expand All @@ -149,8 +154,6 @@ public Object decode(final AbstractByteBuf data, final Class clazz, final Map<St
}
} catch (Exception e) {
throw buildDeserializeError(e.getMessage(), e);
} finally {
fury.clearClassLoader(contextClassLoader);
}
}

Expand All @@ -160,6 +163,7 @@ public void decode(final AbstractByteBuf data, final Object template, final Map<
if (template == null) {
throw buildDeserializeError("template is null!");
}
// See encode() for the rationale of not calling clearClassLoader() here.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
fury.setClassLoader(contextClassLoader);
Expand All @@ -171,8 +175,6 @@ public void decode(final AbstractByteBuf data, final Object template, final Map<
}
} catch (Exception e) {
throw buildDeserializeError(e.getMessage(), e);
} finally {
fury.clearClassLoader(contextClassLoader);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,11 @@ public void updateProviders(ProviderGroup providerGroup) {
closeTransports();
}
} else {
addressHolder.updateProviders(providerGroup);
// Establish connections before making addresses visible to avoid race conditions
// where an address is available but its connection is not yet established.
// See: https://github.com/sofastack/sofa-rpc/issues/1490
connectionHolder.updateProviders(providerGroup);
addressHolder.updateProviders(providerGroup);
}
if (EventBus.isEnable(ProviderInfoUpdateEvent.class)) {
// see: https://github.com/sofastack/sofa-rpc/issues/1442
Expand Down Expand Up @@ -255,8 +258,11 @@ public void updateAllProviders(List<ProviderGroup> providerGroups) {
}
}
} else {
addressHolder.updateAllProviders(providerGroups);
// Establish connections before making addresses visible to avoid race conditions
// where an address is available but its connection is not yet established.
// See: https://github.com/sofastack/sofa-rpc/issues/1490
connectionHolder.updateAllProviders(providerGroups);
addressHolder.updateAllProviders(providerGroups);
}
if (EventBus.isEnable(ProviderInfoUpdateAllEvent.class)) {
ProviderInfoUpdateAllEvent event = new ProviderInfoUpdateAllEvent(consumerConfig, oldProviderGroups,
Expand Down
Loading