-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SERIALIZATION] ClusterBean
Serialization
#1710
Comments
@garyparrot 我想確認一下,在 benchmark 中應該還是會用到 @chinghongfang 可否也看一下? |
我幾個小時前有想到這種方案,我想概念上應該是可行的。如果走上這條路的話,我想我們的序列化檔案裡面可能是存類似 |
感謝確認,直覺上的風險是 sensor 並不接受“過時“的 bean object ? |
感謝提醒,我忘了 不過,透過過濾產新 Metrics 的這個過程,這樣出來的成品好像已經不是 |
沒錯,就是這點讓我擔心。嚴格上來說這是一段「運算過程」,而這個運算過程如果會跟「時間」有關的話,那麼過時的BeanObject就可能導致錯誤。 不過另一個角度是說,如果運算過程會在意資料過時,那麼可能連算成本的時候都會在意資料過時,那可能該cost function 就無法用來做benchmark了 我第一個想到可能會有這個問題的就是「流量成本」, @qoo332001 可否麻煩你也協助確認一下? |
或是說回去嘗試序列化整個 import org.astraea.common.metrics.BeanObject;
import org.astraea.common.metrics.HasBeanObject;
import org.astraea.common.metrics.broker.HasGauge;
import org.astraea.common.metrics.connector.ConnectorInfo;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Map;
public class IgnoreInvokeDynamic {
@Test
@Disabled
void testInvokeDynamic() throws Throwable {
{
// these two variables come from the deserialization result
var deserializedBeanObject = new BeanObject("Domain", Map.of("Hello", "World"), Map.of());
var targetInterface = HasGauge.class;
run(deserializedBeanObject, targetInterface);
}
{
// these two variables come from the deserialization result
var deserializedBeanObject = new BeanObject("Domain", Map.of("Hello", "5566"), Map.of());
var targetInterface = ConnectorInfo.class;
run(deserializedBeanObject, targetInterface);
}
}
void run(BeanObject beanObject, Class<?> typeInterface) throws Throwable {
if(!typeInterface.isInterface())
throw new IllegalArgumentException("The given type has to be interface");
if(typeInterface.isAssignableFrom(HasBeanObject.class))
throw new IllegalArgumentException("The target interface must be assignable from HasBeanObject");
// dynamically create an object with that target type:
// this will work as long as the target type is a functional interface and
// original object didn't store state somewhere else
var callsite = LambdaMetafactory.metafactory(
MethodHandles.lookup(),
"beanObject",
MethodType.methodType(typeInterface, BeanObject.class),
MethodType.methodType(BeanObject.class),
MethodHandles.lookup().findStatic(this.getClass(), "call", MethodType.methodType(BeanObject.class, BeanObject.class)),
MethodType.methodType(BeanObject.class));
var deserializedHasBeanObject = (HasBeanObject) callsite.getTarget().invoke(beanObject);
System.out.println(deserializedHasBeanObject.beanObject());
System.out.println(deserializedHasBeanObject.getClass());
System.out.println(deserializedHasBeanObject.getClass().getInterfaces()[0].getName());
System.out.println(deserializedHasBeanObject instanceof HasBeanObject);
System.out.println(typeInterface.isAssignableFrom(deserializedHasBeanObject.getClass()));
System.out.println();
}
static BeanObject call(BeanObject capture) {
return capture;
}
}
|
這個方案會變成「動態產生的物件」也需要被序列化保存,這個方案在相容性上會有些麻煩,出錯的時候也很難debug,我比較偏向只序列化「固定的物件」也就是 BeanObject,當然這個也有副作用就是前面提到如果有cost很在意當下時間的beans就會出問題...但目前應該沒有這種例子? |
同意這段,如果 Client 沒有對應的 Interface Class 會有恢復上的問題,之前測試的時候也發現這個做法
剛剛檢查了一下,目前沒有這種例子 |
@garyparrot 如果你同意這個做法的話,麻煩說個 +1 :) |
這個做法有他的疑慮,不過 +1 :3 |
@garyparrot 感謝回應 @Haser0305 @chaohengstudent 這部分的序列化設計可以麻煩你們實作嗎? |
好的,沒問題 |
#1506 重複 |
未來 #1693 會有序列化/反序列化
ClusterBean
的需求。這個 Issue 用來討論該如何實作這個需求。
目前最主要的問題是
ClusterBean
內部的變數Map<Integer, Collection<HasBeanObject>>
,這個變數中有用到HasBeanObject
,這個物件目前是一個 Interface,專案內有許多HasBeanObject
是透過 lambda 而非 class 的方式來建立,由於 lambda 建立的 class 是匿名的,我們很難在別的 JVM 上重建這個匿名的 type。The text was updated successfully, but these errors were encountered: