Skip to content

Commit

Permalink
fix async compilation switch for non-public nested class
Browse files Browse the repository at this point in the history
  • Loading branch information
chaokunyang committed Oct 13, 2024
1 parent 0e20458 commit 831ec6c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.fury.Fury;
import org.apache.fury.codegen.Code;
import org.apache.fury.codegen.CodeGenerator;
import org.apache.fury.codegen.CodegenContext;
import org.apache.fury.codegen.Expression;
Expand Down Expand Up @@ -127,7 +128,7 @@ public abstract class BaseObjectCodecBuilder extends CodecBuilder {
private final Map<Class<?>, Reference> serializerMap = new HashMap<>();
private final Map<String, Object> sharedFieldMap = new HashMap<>();
protected final Class<?> parentSerializerClass;
private final Map<String, String> jitCallbackUpdateFields;
private final Map<String, Expression> jitCallbackUpdateFields;
protected LinkedList<String> walkPath = new LinkedList<>();

public BaseObjectCodecBuilder(TypeRef<?> beanType, Fury fury, Class<?> parentSerializerClass) {
Expand Down Expand Up @@ -266,9 +267,13 @@ protected void registerJITNotifyCallback() {
// build encode/decode expr before add constructor to fill up jitCallbackUpdateFields.
if (!jitCallbackUpdateFields.isEmpty()) {
StringJoiner stringJoiner = new StringJoiner(", ", "registerJITNotifyCallback(this,", ");\n");
for (Map.Entry<String, String> entry : jitCallbackUpdateFields.entrySet()) {
for (Map.Entry<String, Expression> entry : jitCallbackUpdateFields.entrySet()) {
Code.ExprCode exprCode = entry.getValue().genCode(ctx);
if (StringUtils.isNotBlank(exprCode.code())) {
stringJoiner.add(exprCode.code());
}
stringJoiner.add("\"" + entry.getKey() + "\"");
stringJoiner.add(entry.getValue());
stringJoiner.add(exprCode.value().toString());
}
// add this code after field serialization initialization to avoid
// it overrides field updates by this callback.
Expand Down Expand Up @@ -526,7 +531,7 @@ protected Expression getOrCreateSerializer(Class<?> cls) {
// `serializerClass` is already jit generated class.
boolean hasJITResult = fury.getJITContext().hasJITResult(cls);
if (hasJITResult) {
jitCallbackUpdateFields.put(name, ctx.type(cls) + ".class");
jitCallbackUpdateFields.put(name, getClassExpr(cls));
ctx.addField(
false, ctx.type(Serializer.class), name, new Cast(newSerializerExpr, SERIALIZER_TYPE));
serializerRef = new Reference(name, SERIALIZER_TYPE, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@
package org.apache.fury.builder;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.List;
import lombok.Data;
import org.apache.fury.Fury;
import org.apache.fury.FuryTestBase;
import org.apache.fury.config.CompatibleMode;
import org.apache.fury.config.Language;
import org.apache.fury.logging.Logger;
import org.apache.fury.logging.LoggerFactory;
import org.apache.fury.reflect.ReflectionUtils;
import org.apache.fury.resolver.MetaContext;
import org.apache.fury.serializer.Serializer;
import org.apache.fury.test.bean.BeanA;
Expand Down Expand Up @@ -131,4 +134,61 @@ public void testAsyncCompilationMetaShared(
if (!scopedMetaShare) fury.getSerializationContext().setMetaContext(context);
assertEquals(fury.deserialize(bytes2), beanA);
}

@Test(timeOut = 60000)
public void testAsyncCompilationSwitch() throws InterruptedException {
final Fury fury =
Fury.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(false)
.withRefTracking(true)
.withAsyncCompilation(true)
.build();

TestAccessLevel o = new TestAccessLevel(new PkgAccessLevel(1), new PrivateAccessLevel(2));
serDeCheck(fury, o);
Class<?>[] classes = {PkgAccessLevel.class, PrivateAccessLevel.class};
for (Class<?> cls : classes) {
while (!(fury.getClassResolver().getSerializer(cls) instanceof Generated)) {
Thread.sleep(1000);
LOG.warn("Wait async compilation finish for {}", cls);
}
}
Serializer<TestAccessLevel> serializer =
fury.getClassResolver().getSerializer(TestAccessLevel.class);
assertTrue(ReflectionUtils.getObjectFieldValue(serializer, "serializer") instanceof Generated);
assertTrue(ReflectionUtils.getObjectFieldValue(serializer, "serializer1") instanceof Generated);
serDeCheck(fury, o);
}

@Data
public static final class TestAccessLevel {
PkgAccessLevel f1;
PrivateAccessLevel f2;

public TestAccessLevel(PkgAccessLevel f1, PrivateAccessLevel f2) {
this.f1 = f1;
this.f2 = f2;
}
}

// test pkg level class
@Data
private static final class PkgAccessLevel {
private final int f1;

public PkgAccessLevel(int f1) {
this.f1 = f1;
}
}

// test private class
@Data
private static final class PrivateAccessLevel {
private final int f1;

public PrivateAccessLevel(int f1) {
this.f1 = f1;
}
}
}

0 comments on commit 831ec6c

Please sign in to comment.