RequestFactory 理论:为什么 Locator<>.find() 被调用得如此频繁? [英] RequestFactory theory: Why is Locator<>.find() being called so often?

查看:23
本文介绍了RequestFactory 理论:为什么 Locator<>.find() 被调用得如此频繁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 RequestFactory 的新手,但在 Thomas Broyer 的慷慨帮助下,在查看了下面的文档后,我发现了很多更好:)

I'm new to RequestFactory but with generous help of Thomas Broyer and after reviewing documents below it's getting much better :)

但是你能解释一下为什么 Locator<>.find() 经常被不必要地调用(在我看来)?

But could you please explain why Locator<>.find() is being called so unnecessarily (in my opinion) often ?

在我的示例项目中,我有两个实体 Organization 和 Person 维护父子关系.当我获取 Organization Objectify 时自动获取子人.我还在我的服务层 findOrganizationByIdsaveOrganization 中创建了两个方法来加载和持久化对象.

In my sample project I have two entities Organization and Person that maintain parent-child relationship. When I fetch Organization Objectify automatically fetches child Person. Also I created two methods in my service layer findOrganizationById and saveOrganization that load and persist objects.

现在考虑两种情况:

当我在客户端调用 findOrganizationById 时,服务器端发生以下调用:

When I call findOrganizationById in the client following calls occur on server side:

OrderDao.findOrganizationById(1)
PojoLocator.getId(Key<?>(Organization(1)))
PojoLocator.getId(Key<?>(Organization(1)/Person(2)))
PojoLocator.getId(Key<?>(Organization(1)))
PojoLocator.find(Key<?>(Organization(1)))
PojoLocator.getId(Key<?>(Organization(1)/Person(2)))
PojoLocator.find(Key<?>(Organization(1)/Person(2)))

通过调用 OrderDao.findOrganizationById 我已经收到了完整的对象图.除此之外,为什么还要调用 .find 两次?Datastore 上的额外负载让我花钱.当然我缓存它,但修复它会很好.如何避免这些额外的调用?

By calling OrderDao.findOrganizationById I've already received full graph of objects. Why call .find twice in addition to that? It's extra load on Datastore that cost me money. Of course I cache it but it would be neat to fix it. How can I avoid these additional calls ?

当我通过在客户端调用 saveOrganization 来保存对象时,会发生类似的事情.以下调用发生在服务器端:

Similar thing happens when I save object(s) by calling saveOrganization in the client. Following calls occur on server side:

PojoLocator.find(Key<?>(Organization(1)))
PojoLocator.find(Key<?>(Organization(1)/Person(2)))
OrderDao.saveOrganization(1)
PojoLocator.getId(Key<?>(Organization(1)))
PojoLocator.find(Key<?>(Organization(1)))
PojoLocator.getId(Key<?>(Organization(1)/Person(2)))
PojoLocator.find(Key<?>(Organization(1)/Person(2)))

我可以理解在更新数据存储之前需要从数据存储中获取两个对象.RequestFactory 将 deltas 发送到服务器,因此它需要在持久化之前拥有整个对象.尽管如此,因为我一次加载完整图,所以最好不要第二次调用 PojoLocator.find(Key<?>(Organization(1)/Person(2))).而且我真的无法理解需要 .find() 调用 after 持久化.

I can understand need for fetching two objects from DataStore before updating it. RequestFactory sends deltas to the server so it needs to have entire object before persisting it. Still since I load full graph at once it would be nice not to have second call which is PojoLocator.find(Key<?>(Organization(1)/Person(2))). And I truly can't understand need for .find() calls after persisting.

想法?

我的代理

@ProxyFor(value = Organization.class, locator = PojoLocator.class)
public interface OrganizationProxy extends EntityProxy
{
    public String getName();
    public void setName(String name);
    public String getAddress();
    public void setAddress(String address);
    public PersonProxy getContactPerson();
    public void setContactPerson(PersonProxy contactPerson);
    public EntityProxyId<OrganizationProxy> stableId();
}

@ProxyFor(value = Person.class, locator = PojoLocator.class)
public interface PersonProxy extends EntityProxy
{
    public String getName();
    public void setName(String name);
    public String getPhoneNumber();
    public void setPhoneNumber(String phoneNumber);
    public String getEmail();
    public void setEmail(String email);
    public OrganizationProxy getOrganization();
    public void setOrganization(OrganizationProxy organization);
}

我的服务

public interface AdminRequestFactory extends RequestFactory
{
    @Service(value = OrderDao.class, locator = InjectingServiceLocator.class)
    public interface OrderRequestContext extends RequestContext
    {
        Request<Void> saveOrganization(OrganizationProxy organization);
        Request<OrganizationProxy> findOrganizationById(long id);
    }

    OrderRequestContext contextOrder();
}

最后是我的定位器<>

public class PojoLocator extends Locator<DatastoreObject, String>
{
    @Inject Ofy ofy;

    @Override
    public DatastoreObject create(Class<? extends DatastoreObject> clazz)
    {
        try
        {
            return clazz.newInstance();
        } catch (InstantiationException e)
        {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
    {
        Key<DatastoreObject> key = Key.create(id);
        DatastoreObject load = ofy.load(key);
        return load;
    }

    @Override
    public Class<DatastoreObject> getDomainType()
    {
        return null;    // Never called
    }

    @Override
    public String getId(DatastoreObject domainObject)
    {
        Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
        return key.getString();
    }

    @Override
    public Class<String> getIdType()
    {
        return String.class;
    }

    @Override
    public Object getVersion(DatastoreObject domainObject)
    {
        return domainObject.getVersion();
    }
}

推荐答案

末尾的 getIdfind 对是 Locator# 的默认实现isLive:如果通过它的 ID 找到它返回一个非空值,它假定一个对象是 live(即仍然存在于数据存储中).

The pairs of getId and find at the end are the default implementation of Locator#isLive: it assumes an object is live (i.e. still exists in the data store) if finding it by its ID returns a non-null value.

RF 在构建响应时检查它在请求/响应期间看到的每个 EntityProxy活性,以告诉客户端实体何时被删除(在客户端,然后它会触发一个带有 DELETE write 操作EntityProxyChange 事件.

RF checks each EntityProxy it ever seen during the request/response for their liveness when constructing the response, to tell the client when an entity has been deleted (on the client side, it'd then fire an EntityProxyChange event with a DELETE write operation.

您当然可以在您的 Locator 中使用更优化的实现覆盖 isLive,如果您能提供的话.

You can of course override isLive in your Locator with a more optimized implementation if you can provide one.

这篇关于RequestFactory 理论:为什么 Locator&lt;&gt;.find() 被调用得如此频繁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆