3

巨大な DTO を送信するサーバー側サービスがあります。それらをCellTableに入れる必要があります。10 ~ 200 行ほどあるので、すべてを同時に見る必要があります。

サービスの最後の「人為的な」コード行 (リターンの直前) をトレースするサーバー側のログがあります。

最良のシナリオでは、このログと完全に読み込まれたテーブルの間に 2 分のギャップがあります。ほとんどの場合、プロセスの途中で何かが壊れてしまい、私は立ち往生してしまいます。

私のオプションは何ですか?

ありがとう

編集:データダウンロードの長さ(rpcコールバック)とセルテーブルのロードの長さを区別して、アンドレイのアイデアを試しました。

確認したかったので、コールバックで行ったことは次のとおりです。

@Override
public void onSuccess(ResponseBean result) {
  Window.alert("success " + new Date().toString());

  resultPanel.updateResults(result);

  Window.alert("celltable " + new Date().toString());
}

最初のアラートは ~10 秒後に発生します。しかし、2番目のものは決して呼び出されません。

これは updateResults の背後にあるメソッドです:

public void updateResults(ResponseBean response) {
  dataProvider.getList().clear();
  dataProvider.getList().addAll(response.beans());
  myCellTable.setPageSize(response.beans.size());
}

EDIT 2:私は多くのことを試しました。セルテーブルにデータを入力しようとすると、問題が発生します。Chrome では、BSOD の Chrome バージョンが表示されます。Firefox では、黙って中断しますが、残りの js 命令は実行されません。firebug でコンソールを読み取ろうとすると、firefox が ~2.5 GB の RAM を使用してフリーズします。gwt-runner を使用すると、それもフリーズします。

私の例では、4 つの行 (複数の依存関係を持つ 4 つのオブジェクト) しかありません。

WHAT break と WHERE を見つけるにはどうすればよいですか?

助けてくれてありがとう:)

最後に : わかりました。getValues() のどこかに、そこにあってはならない「ビジネス ロジック」があり、それが OutOfMemory エラーを引き起こしていました。

ただし、要点:

  • サーバー側の最後の呼び出しとクライアント側の onSuccess の最初の行をトレースして、問題が RPC に関連しているかどうかを確認します。
  • セルテーブルが壊れても数行しかない場合は、誇りに思わないことをしました
  • Scheduler.get().scheduleDeffered を使用すると、ページをレンダリングしてから、ビジネス ロジックを実行できます。かっこいいですね。

みんなありがとう

4

2 に答える 2

3

CellTable通常、レンダリングではなく RPC シリアライゼーションがボトルネックであることに賭けます。
ただし、最初のアラートが 10 秒後に表示されると言っているのは、それに反することです。

200 DTO のレンダリングは、CellTable.
また、ネットワーク経由で 200 個の DTO を送信しても問題ありません。

私はCellTable約 5000 の DTO を使用し、ネットワーク経由で送信しましたが、パフォーマンスの問題はありませんでした (ただし、一度に 50 しか表示せず、ページングを使用しています)。

いくつかの考え:

  • 開発モードは、プロダクション モードよりもはるかに低速です (特にデシリアライゼーションに関して)。そのため、本番モードでもパフォーマンスをテストします。
  • 問題の正確な原因を突き止めるには、Chrome Dev Tools を使用します。コードをプロファイリングして、遅延の原因を確認できます。
  • コードで 200 個のダミー DTO を手動で作成し、それを関数に渡してupdateResults、パフォーマンスがどのように比較されるかを確認できますか。
  • 何列表示しますか?多数の列を表示する場合は、1 つだけに減らして、パフォーマンスへの影響を確認してください。
  • CellTable 列で使用される getter には、高価なビジネス ロジックがありますか?
于 2012-09-26T08:13:34.310 に答える
1

その量のデータには、ポケットベルとAsyncDataProviderを使用する必要があります。これは、これを行う方法のテンプレートです。それはあなたのニーズに完全ではないかもしれませんが、それはあなたに出発点を与えるでしょう。DatastoreObjectProxyはEntityProxyから拡張され、リクエストファクトリを使用してアイテムをフェッチします。このデータプロバイダーにテーブルを追加すると、ページャーがデータのチャンクのフェッチを処理します。

public abstract class DaoBaseDataProvider<T extends DatastoreObjectProxy> extends AsyncDataProvider<T> implements SearchProvider<T> {

    public static final ProvidesKey<DatastoreObjectProxy> KeyProvider = new ProvidesKey<DatastoreObjectProxy>() {

        @Override
        public Long getKey(DatastoreObjectProxy item) {
            return item.getId();
        }
    };

    public interface HasBaseDataProvider<T extends DatastoreObjectProxy> {
        public void setDataProvider(DaoBaseDataProvider<T> dataProvider);

        public void setSelectionModel(SelectionModel<? super T> selectionModel);
    }

    public DaoBaseDataProvider() {
        super(new ProvidesKey<T>() {
            public Long getKey(T item) {
                // Always do a null check.
                return (item == null) ? null : item.getId();
            }
        });
    }

    @Override
    public void search(String searchText) {

        getSearchQuery(searchText).fire(new Receiver<List<T>>() {

            @Override
            public void onSuccess(List<T> values) {
                updateRowData(0, values);
                updateRowCount(values.size(), true);
            }
        });
    }

    public void showAll() {
        updateRowCount(10, false);
    }

    @Override
    protected void onRangeChanged(HasData<T> display) {
        final Range range = display.getVisibleRange();

        Request<List<T>> request = getRangeQuery(range);
        if (getWithProperties() != null) {
            request.with(getWithProperties());
        }

        request.fire(new Receiver<List<T>>() {

            @Override
            public void onSuccess(List<T> values) {
                updateRowData(range.getStart(), values);
            }
        });
    }

    public abstract String[] getWithProperties();

    public abstract DaoRequest<T> getRequestProvider();

    public void remove(final Set<Long> idsToDelete) {
        getDeleteQuery(idsToDelete).fire(new Receiver<Integer>() {

            @Override
            public void onSuccess(Integer response) {
                for (HasData<T> display : getDataDisplays()) {
                    // Force the display to relaod it's view.
                    display.setVisibleRangeAndClearData(display.getVisibleRange(), true);
                }
            }
        });
    }

    /**
     * This can be overridden so that you can change the query.
     * 
     * @param range
     * @return
     */
    protected Request<List<T>> getRangeQuery(Range range) {
        Request<List<T>> request = getRequestProvider().findRange(range.getStart(), range.getLength());
        if (getWithProperties() != null) {
            request.with(getWithProperties());
        }
        return request;
    }

    protected Request<List<T>> getSearchQuery(String searchText) {
        Request<List<T>> request = getRequestProvider().search(searchText).with(getWithProperties());
        if (getWithProperties() != null) {
            request.with(getWithProperties());
        }
        return request;

    }

    protected Request<Integer> getDeleteQuery(Set<Long> idsToDelete) {
        return getRequestProvider().deleteList(idsToDelete);
    }
}

これは、オブジェクトをフェッチするために使用されるクライアント側のクラスです。これを独自のRequestContextで拡張します。

public interface DaoRequestFactory extends RequestFactory {

    @Service(value = DaoBase.class, locator = DaoServiceLocator.class)
    public interface DaoRequest<T extends DatastoreObjectProxy> extends RequestContext {

        Request<T> find(Long id);

        Request<List<T>> findRange(int start, int end);

        Request<Integer> deleteList(Set<Long> idsToDelete);

        Request<List<T>> search(String searchText);

        Request<Long> save(T obj);

        Request<Void> delete(Long objId);
    }
}
于 2012-09-25T22:20:10.313 に答える