Author: manolo
Date: Tue May 8 09:40:06 2012
New Revision: 1335396
URL: http://svn.apache.org/viewvc?rev=1335396&view=rev
Log:
Some cache improvements in client side. Fix parallel fetching of messages on
loading
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/CachingDispatchAsync.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaClientModule.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaGinjector.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageTableModel.java
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/place/IMAPMessageListPresenterPlace.java
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/CachingDispatchAsync.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/CachingDispatchAsync.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/CachingDispatchAsync.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/CachingDispatchAsync.java
Tue May 8 09:40:06 2012
@@ -20,64 +20,112 @@
package org.apache.hupa.client;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.inject.Inject;
+import org.apache.hupa.shared.rpc.GetMessageDetails;
-import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.dispatch.client.ExceptionHandler;
+import net.customware.gwt.dispatch.client.standard.StandardDispatchAsync;
import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.inject.Inject;
+
/**
- * Dispatcher which support caching of data in memory
+ * Dispatcher which support caching of data in memory.
+ *
+ * It also avoids simultaneous executions of the same action, which
+ * is very useful in development.
*
*/
-public class CachingDispatchAsync implements DispatchAsync {
-
- private DispatchAsync dispatcher;
- private Map<Action<Result>, Result> cache = new HashMap<Action<Result>,
Result>();
+public class CachingDispatchAsync extends StandardDispatchAsync {
+
@Inject
- public CachingDispatchAsync(DispatchAsync dispatcher) {
- this.dispatcher = dispatcher;
+ public CachingDispatchAsync(ExceptionHandler exceptionHandler) {
+ super(exceptionHandler);
}
- /*
- * (non-Javadoc)
- * @see net.customware.gwt.dispatch.client.DispatchAsync#execute(A,
com.google.gwt.user.client.rpc.AsyncCallback)
- */
+ private Map<Action<Result>, Result> cache = new HashMap<Action<Result>,
Result>();
+
+ private HashSet<Class<?>> running = new HashSet<Class<?>>();
+
+ @Override
public <A extends Action<R>, R extends Result> void execute(final A action,
final AsyncCallback<R> callback) {
- dispatcher.execute(action, callback);
+
+ if (action instanceof GetMessageDetails) {
+ executeWithCache(action, callback);
+ } else {
+ if (GWT.isProdMode()) {
+ super.execute(action, callback);
+ } else {
+ executeOneRequestPerAction(action, callback);
+ }
+ }
+ }
+
+ /**
+ * Avoid parallel executions of the same action
+ */
+ public <A extends Action<R>, R extends Result> void
executeOneRequestPerAction (
+ final A action, final AsyncCallback<R> callback) {
+
+ final Class<?> clz = action.getClass();
+ if (running.contains(clz)) {
+ System.err.println("ATTENTION: avoiding a parallel execution of
the action: " + action.getClass().getName());
+ new RuntimeException().printStackTrace();
+
+ return;
+ } else {
+ running.add(clz);
+ super.execute(action, new AsyncCallback<R>() {
+ public void onFailure(Throwable caught) {
+ running.remove(clz);
+ callback.onFailure(caught);
+ }
+ public void onSuccess(final R result) {
+ running.remove(clz);
+ callback.onSuccess(result);
+ }
+ });
+ }
}
/**
- * Execute the give Action. If the Action was executed before it will get
fetched from the cache
- *
- * @param <A> Action implementation
- * @param <R> Result implementation
- * @param action the action
- * @param callback the callback
+ * If the Action was executed before it will get fetched from the cache
*/
@SuppressWarnings("unchecked")
public <A extends Action<R>, R extends Result> void executeWithCache(
final A action, final AsyncCallback<R> callback) {
Result r = cache.get(action);
+
+ final Class<?> clz = action.getClass();
+ if (running.contains(clz)) {
+ System.out.println("Contanins " + clz);
+ return;
+ } else {
+ System.out.println("new " + clz);
+ running.add(clz);
+ }
+
if (r != null) {
callback.onSuccess((R) r);
} else {
- dispatcher.execute(action, new AsyncCallback<R>() {
-
+ super.execute(action, new AsyncCallback<R>() {
public void onFailure(Throwable caught) {
+ running.remove(clz);
callback.onFailure(caught);
}
public void onSuccess(R result) {
+ running.remove(clz);
cache.put((Action<Result>) action, (Result) result);
callback.onSuccess(result);
}
-
});
}
}
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaClientModule.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaClientModule.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaClientModule.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaClientModule.java
Tue May 8 09:40:06 2012
@@ -19,6 +19,9 @@
package org.apache.hupa.client.gin;
+import net.customware.gwt.dispatch.client.DefaultExceptionHandler;
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.dispatch.client.ExceptionHandler;
import net.customware.gwt.presenter.client.DefaultEventBus;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.gin.AbstractPresenterModule;
@@ -53,6 +56,7 @@ import org.apache.hupa.client.rf.HupaReq
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.inject.Provider;
+import com.google.inject.Provides;
import com.google.inject.Singleton;
public class HupaClientModule extends AbstractPresenterModule {
@@ -69,22 +73,35 @@ public class HupaClientModule extends Ab
bindPresenter(MessageSendPresenter.class,
MessageSendPresenter.Display.class, MessageSendView.class);
bindPresenter(AppPresenter.class, AppPresenter.Display.class,
AppView.class);
bindPresenter(ContactsPresenter.class,
ContactsPresenter.Display.class, ContactsView.class);
- bind(CachingDispatchAsync.class);
bind(PagingScrollTableRowDragController.class).in(Singleton.class);
bind(MessageTableModel.class).in(Singleton.class);
bind(LoginPresenterPlace.class).in(Singleton.class);
bind(IMAPMessageListPresenterPlace.class).in(Singleton.class);
bind(MessageSendPresenterPlace.class).in(Singleton.class);
bind(ContactsPresenterPlace.class).in(Singleton.class);
+
+ // Used by dispatch. Note that GWT 2.4 has its own ExceptionHandler
etc in other namespace
+ bind(ExceptionHandler.class).to(DefaultExceptionHandler.class);
+ // RF Stuff, Eventbus has a different namespace than gwt-dispatch
bind(com.google.gwt.event.shared.EventBus.class)
.to(SimpleEventBus.class)
.in(Singleton.class);
bind(HupaRequestFactory.class)
.toProvider(HupaClientModule.RequestFactoryProvider.class)
.in(Singleton.class);
+
+ }
+
+ @Provides
+ @Singleton
+ protected DispatchAsync provideDispatchAsync(ExceptionHandler
exceptionHandler) {
+ return new CachingDispatchAsync( exceptionHandler );
}
+ /**
+ * RF Stuff
+ */
public static class RequestFactoryProvider implements
Provider<HupaRequestFactory> {
private static final com.google.gwt.event.shared.EventBus eventBus =
new SimpleEventBus();
public HupaRequestFactory get() {
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaGinjector.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaGinjector.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaGinjector.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/gin/HupaGinjector.java
Tue May 8 09:40:06 2012
@@ -28,7 +28,7 @@ import org.apache.hupa.client.rf.HupaReq
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
-@GinModules({StandardDispatchModule.class,HupaClientModule.class})
+@GinModules({/*StandardDispatchModule.class,*/ HupaClientModule.class})
public interface HupaGinjector extends Ginjector {
AppPresenter getAppPresenter();
PlaceManager getPlaceManager();
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListPresenter.java
Tue May 8 09:40:06 2012
@@ -404,20 +404,28 @@ public class IMAPMessageListPresenter ex
@Override
protected void onRevealDisplay() {
- display.reloadData();
+ if (user != null && folder != null) {
+ display.reloadData();
+ }
}
public void revealDisplay(User user, IMAPFolder folder, String
searchValue) {
this.user = user;
- if (this.folder == null ||
this.folder.getFullName().equals(folder.getFullName()) == false
- || (searchValue == null && this.searchValue != null) ||
(searchValue != null && searchValue.equals(this.searchValue) == false)) {
+ if (this.user == null
+ || !this.user.getName().equals(user.getName())
+ || this.folder == null
+ || !this.folder.getFullName().equals(folder.getFullName())
+ || (searchValue == null && this.searchValue != null)
+ || (searchValue != null && searchValue.equals(this.searchValue) ==
false)) {
display.reset();
display.deselectAllMessages();
}
display.setExpandLoading(false);
this.searchValue = searchValue;
this.folder = folder;
+
+
revealDisplay();
}
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
Tue May 8 09:40:06 2012
@@ -474,7 +474,7 @@ public class IMAPMessageListView extends
pageBox.setSelectedIndex(0);
cTableModel.clearCache();
cTableModel.setRowCount(CachedTableModel.UNKNOWN_ROW_COUNT);
- mailTable.gotoFirstPage();
+// mailTable.gotoFirstPage();
}
/*
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
Tue May 8 09:40:06 2012
@@ -24,20 +24,20 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.widget.WidgetContainerDisplay;
import net.customware.gwt.presenter.client.widget.WidgetContainerPresenter;
-import org.apache.hupa.client.CachingDispatchAsync;
import org.apache.hupa.client.HupaCallback;
import org.apache.hupa.client.mvp.MessageSendPresenter.Type;
import org.apache.hupa.client.widgets.HasDialog;
import org.apache.hupa.client.widgets.IMAPTreeItem;
import org.apache.hupa.shared.data.IMAPFolder;
import org.apache.hupa.shared.data.Message;
+import org.apache.hupa.shared.data.Message.IMAPFlag;
import org.apache.hupa.shared.data.MessageDetails;
import org.apache.hupa.shared.data.User;
-import org.apache.hupa.shared.data.Message.IMAPFlag;
import org.apache.hupa.shared.events.BackEvent;
import org.apache.hupa.shared.events.BackEventHandler;
import org.apache.hupa.shared.events.DecreaseUnseenEvent;
@@ -129,7 +129,7 @@ public class MainPresenter extends Widge
}
- private CachingDispatchAsync cachingDispatcher;
+ private DispatchAsync dispatcher;
private User user;
private IMAPFolder folder;
private String searchValue;
@@ -140,10 +140,10 @@ public class MainPresenter extends Widge
private HasEditable editableTreeItem;
@Inject
- public MainPresenter(MainPresenter.Display display, EventBus bus,
CachingDispatchAsync cachingDispatcher, IMAPMessageListPresenter
messageListPresenter, IMAPMessagePresenter messagePresenter,
+ public MainPresenter(MainPresenter.Display display, EventBus bus,
DispatchAsync cachingDispatcher, IMAPMessageListPresenter messageListPresenter,
IMAPMessagePresenter messagePresenter,
MessageSendPresenter sendPresenter) {
super(display, bus, messageListPresenter, messagePresenter,
sendPresenter);
- this.cachingDispatcher = cachingDispatcher;
+ this.dispatcher = cachingDispatcher;
this.messageListPresenter = messageListPresenter;
this.messagePresenter = messagePresenter;
this.sendPresenter = sendPresenter;
@@ -152,7 +152,7 @@ public class MainPresenter extends Widge
protected void loadTreeItems() {
display.setLoadingFolders(true);
- cachingDispatcher.execute(new FetchFolders(), new
HupaCallback<FetchFoldersResult>(cachingDispatcher, eventBus, display) {
+ dispatcher.execute(new FetchFolders(), new
HupaCallback<FetchFoldersResult>(dispatcher, eventBus, display) {
public void callback(FetchFoldersResult result) {
display.bindTreeItems(createTreeNodes(result.getFolders()));
// disable
@@ -183,7 +183,7 @@ public class MainPresenter extends Widge
IMAPFolder iFolder = new IMAPFolder((String)
event.getOldValue());
final String newName = (String) event.getNewValue();
if (iFolder.getFullName().equalsIgnoreCase(newName) ==
false) {
- cachingDispatcher.execute(new
RenameFolder(iFolder, newName), new
HupaCallback<GenericResult>(cachingDispatcher, eventBus) {
+ dispatcher.execute(new RenameFolder(iFolder,
newName), new HupaCallback<GenericResult>(dispatcher, eventBus) {
public void callback(GenericResult result) {
folder.setFullName(newName);
}
@@ -255,14 +255,6 @@ public class MainPresenter extends Widge
sendPresenter.revealDisplay();
}
- /**
- * Reset the presenter and display
- */
- private void reset() {
- // clear the cache
- cachingDispatcher.clear();
- }
-
@Override
protected void onBind() {
@@ -289,7 +281,7 @@ public class MainPresenter extends Widge
}
display.setLoadingMessage(true);
- cachingDispatcher.executeWithCache(new
GetMessageDetails(event.getFolder(), message.getUid()), new
HupaCallback<GetMessageDetailsResult>(cachingDispatcher, eventBus, display) {
+ dispatcher.execute(new GetMessageDetails(event.getFolder(),
message.getUid()), new HupaCallback<GetMessageDetailsResult>(dispatcher,
eventBus, display) {
public void callback(GetMessageDetailsResult result) {
if (decreaseUnseen) {
eventBus.fireEvent(new DecreaseUnseenEvent(user,
folder));
@@ -430,7 +422,7 @@ public class MainPresenter extends Widge
registerHandler(display.getDeleteConfirmClick().addClickHandler(new
ClickHandler() {
public void onClick(ClickEvent event) {
- cachingDispatcher.execute(new DeleteFolder(folder), new
AsyncCallback<GenericResult>() {
+ dispatcher.execute(new DeleteFolder(folder), new
AsyncCallback<GenericResult>() {
public void onFailure(Throwable caught) {
GWT.log("ERROR while deleting", caught);
@@ -454,7 +446,7 @@ public class MainPresenter extends Widge
final IMAPTreeItem item = (IMAPTreeItem)
event.getSource();
final String newValue = (String) event.getNewValue();
if
(event.getEventType().equals(EditEvent.EventType.Stop)) {
- cachingDispatcher.execute(new CreateFolder(new
IMAPFolder(newValue.trim())), new AsyncCallback<GenericResult>() {
+ dispatcher.execute(new CreateFolder(new
IMAPFolder(newValue.trim())), new AsyncCallback<GenericResult>() {
public void onFailure(Throwable caught) {
GWT.log("Error while create folder",
caught);
@@ -487,8 +479,9 @@ public class MainPresenter extends Widge
public void onLogin(LoginEvent event) {
user = event.getUser();
- folder = new
IMAPFolder(user.getSettings().getInboxFolderName());
- messageListPresenter.revealDisplay(user, folder, null);
+ folder = new
IMAPFolder(user.getSettings().getInboxFolderName());;
+ searchValue = null;
+ showMessageTable(user, folder, searchValue);
}
}));
@@ -498,15 +491,6 @@ public class MainPresenter extends Widge
}
-
- @Override
- protected void onUnbind() {
- reset();
-
- super.onUnbind();
- }
-
-
public void revealDisplay(User user) {
this.user = user;
loadTreeItems();
@@ -515,8 +499,8 @@ public class MainPresenter extends Widge
@Override
protected void onRevealDisplay() {
- showMessageTable(user, folder, searchValue);
- super.onRevealDisplay();
+// showMessageTable(user, folder, searchValue);
+// super.onRevealDisplay();
}
public void openLink(String url) {
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageTableModel.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageTableModel.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageTableModel.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageTableModel.java
Tue May 8 09:40:06 2012
@@ -122,9 +122,9 @@ public class MessageTableModel extends M
// Update folder information before notifying presenter
folder.setMessageCount(result.getRealCount());
folder.setUnseenMessageCount(result.getRealUnreadCount());
- // Notify presenter to update folder tree view
- eventBus.fireEvent(new MessagesReceivedEvent(folder,
result.getMessages()));
- TableModelHelper.Response<Message> response = new
TableModelHelper.Response<Message>() {
+
+ setRowCount(result.getRealCount());
+ callback.onRowsReady(request, new
TableModelHelper.Response<Message>() {
@Override
public Iterator<Message> getRowValues() {
if (result != null && result.getMessages() != null) {
@@ -133,9 +133,10 @@ public class MessageTableModel extends M
return new ArrayList<Message>().iterator();
}
}
- };
- setRowCount(result.getRealCount());
- callback.onRowsReady(request,response);
+ });
+
+ // Notify presenter to update folder tree view
+ eventBus.fireEvent(new MessagesReceivedEvent(folder,
result.getMessages()));
}
});
}
Modified:
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/place/IMAPMessageListPresenterPlace.java
URL:
http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/place/IMAPMessageListPresenterPlace.java?rev=1335396&r1=1335395&r2=1335396&view=diff
==============================================================================
---
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/place/IMAPMessageListPresenterPlace.java
(original)
+++
james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/place/IMAPMessageListPresenterPlace.java
Tue May 8 09:40:06 2012
@@ -55,7 +55,6 @@ public class IMAPMessageListPresenterPla
} catch (NumberFormatException e) {
// ignore
}
- presenter.getDisplay().goToPage(page);
int rowsPerPageIndex = 0;
try {
@@ -70,8 +69,9 @@ public class IMAPMessageListPresenterPla
String searchValue = request.getParameter(SEARCH, "");
presenter.getDisplay().getSearchValue().setValue(searchValue);
+ presenter.getDisplay().goToPage(page);
+
GWT.log("PRES="+request.toString(),null);
-
}
@Override
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]