Package org.rstudio.studio.client.workbench

Source Code of org.rstudio.studio.client.workbench.ClientStateUpdater

/*
* ClientStateUpdater.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.workbench;

import com.google.inject.Inject;
import org.rstudio.core.client.Barrier.Token;
import org.rstudio.core.client.TimeBufferedCommand;
import org.rstudio.studio.client.application.Desktop;
import org.rstudio.studio.client.application.events.EventBus;
import org.rstudio.studio.client.server.ServerError;
import org.rstudio.studio.client.server.ServerRequestCallback;
import org.rstudio.studio.client.server.Void;
import org.rstudio.studio.client.workbench.events.*;
import org.rstudio.studio.client.workbench.model.ClientState;
import org.rstudio.studio.client.workbench.model.WorkbenchServerOperations;

public class ClientStateUpdater extends TimeBufferedCommand
{
   /**
    * "Client state" collectively refers to the set of stuff that the
    * client would like to remember for the next time we connect.
    *
    * Components that would like to participate in saving client state should
    * add a handler to SaveClientStateEvent on EventBus, and in
    * that handler, add values to the ClientState if they have changed.
    * Values that are unchanged since the last update need not be added,
    * as the values that are put in ClientState will be merged with previous
    * values.
    *
    * The SaveClientStateEvent fires either passively (on a timer) or actively
    * (on request [though in fact also on a timer, just a shorter one]). Any
    * component can request that SaveClientStateEvent be fired: simply fire
    * PushClientStateEvent on the EventBus.
    */
   @Inject
   public ClientStateUpdater(EventBus events,
                             WorkbenchServerOperations server)
   {
      super(INITIAL_INTERVAL_MILLIS, PASSIVE_INTERVAL_MILLIS, ACTIVE_INTERVAL_MILLIS);
      events_ = events;
      server_ = server;

      events_.addHandler(PushClientStateEvent.TYPE, new PushClientStateHandler()
      {
         public void onPushClientState(PushClientStateEvent event)
         {
            // Don't allow active pushes until after the initial interval
            // has elapsed. This lets us avoid storms of requests during
            // startup.
            if (lastExecuted_ != null)
               nudge();
         }
      });

      events_.addHandler(LastChanceSaveEvent.TYPE, new LastChanceSaveHandler()
      {
         public void onLastChanceSave(LastChanceSaveEvent event)
         {
            // We're quitting. Save client state one more time.

            barrierToken_ = event.acquire();
            nudge();
         }
      });
   }

   @Override
   protected void performAction(final boolean shouldSchedulePassive)
   {
      ClientState state = ClientState.create();
      try
      {
         events_.fireEvent(new SaveClientStateEvent(state));
      }
      catch (Exception e)
      {
         onComplete(shouldSchedulePassive);
         return;
      }

      if (state.isEmpty())
      {
         onComplete(shouldSchedulePassive);
         return;
      }

      server_.updateClientState(
            state.getTemporaryData(),
            state.getPersistentData(),
            state.getProjectPersistentData(),
            new ServerRequestCallback<Void>() {
               @Override
               public void onError(ServerError error)
               {
                  onComplete(shouldSchedulePassive);
               }

               @Override
               public void onResponseReceived(Void response)
               {
                  onComplete(shouldSchedulePassive);
               }
            });
   }

   private void onComplete(boolean shouldSchedulePassive)
   {
      if (barrierToken_ != null)
         barrierToken_.release();
      if (shouldSchedulePassive)
         schedulePassive();
   }

   private static final int INITIAL_INTERVAL_MILLIS = 2000;
   private static final int PASSIVE_INTERVAL_MILLIS = 5000;
   private static final int ACTIVE_INTERVAL_MILLIS = Desktop.isDesktop()
                                                     ? 100
                                                     : 350;
   private final EventBus events_;
   private final WorkbenchServerOperations server_;
   private Token barrierToken_;
}
TOP

Related Classes of org.rstudio.studio.client.workbench.ClientStateUpdater

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.