Package com.almende.eve.scheduler.google

Source Code of com.almende.eve.scheduler.google.GaeSchedulerFactory$AppEngineScheduler

package com.almende.eve.scheduler.google;

import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.joda.time.DateTime;

import com.almende.eve.agent.Agent;
import com.almende.eve.agent.AgentHost;
import com.almende.eve.rpc.annotation.Access;
import com.almende.eve.rpc.annotation.AccessType;
import com.almende.eve.rpc.jsonrpc.JSONRequest;
import com.almende.eve.scheduler.AbstractScheduler;
import com.almende.eve.scheduler.SchedulerFactory;
import com.almende.eve.transport.TransportService;
import com.almende.util.TwigUtil;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskHandle;
import com.google.code.twig.ObjectDatastore;
import com.google.code.twig.annotation.AnnotationObjectDatastore;

public class GaeSchedulerFactory implements SchedulerFactory {
  private AgentHost agentFactory = null;

  // private Logger logger = Logger.getLogger(this.getClass().getSimpleName());

  /**
   * This constructor is called when constructed by the AgentFactory
   * @param agentFactory
   * @param params
   */
  public GaeSchedulerFactory (AgentHost agentFactory,
      Map<String, Object> params) {
    this.agentFactory = agentFactory;
    TwigUtil.register(GaeTask.class);
  }
 
  protected GaeSchedulerFactory () {}
 
  /**
   * Get a scheduler for specified agent
   * @param agentId
   * @return scheduler
   */
  public AppEngineScheduler getScheduler(Agent agent) {
    return new AppEngineScheduler(agent.getId());
  }

  /**
   * AppEngineScheduler
   * A scheduler for a single agent.
   *
   */
  public class AppEngineScheduler extends AbstractScheduler {
    /**
     * constructor
     * @param agentId
     */
    private AppEngineScheduler(String agentId) {
      this.agentId = agentId;
    }
   

    /**
     * Schedule a task
     * @param request   A JSONRequest with method and params
     * @param delay     The delay in milliseconds
     * @return taskId
     */
    @Override
    public String createTask(JSONRequest request, long delay) {
      return createTask(request, delay, false, false);
    }
    /**
     * Schedule a task
     * @param request   A JSONRequest with method and params
     * @param delay     The delay in milliseconds
     * @param interval   Should the task be repeated at an interval?
     * @param sequential Should (long running) tasks run sequential, or may they run in parallel?
     * @return taskId
     */
    @Override
    public String createTask(JSONRequest request, long delay, boolean interval, boolean sequential) {
      try {
       
        if (interval){
          //TODO: fix this!
          System.err.println("WARNING: interval scheduling is not supported by Eve on Google App Engine, only running once!");
        }
       
        // TODO: getting an arbitrary http service which knows this agent
        //       is not safe
        //       -> Scheduler should be configured with the servlet_url
        //          that it should use specified?
        TransportService service = null;
        for (TransportService s : agentFactory.getTransportServices("http")) {
          if (s.getAgentUrl(agentId) != null) {
            service = s;
            break;
          }
        }
        String url = null;
        if (service != null) {
          url = service.getAgentUrl(agentId);
        }
       
        URL uri = new URL(url);
        String path = uri.getPath();   
        Queue queue = QueueFactory.getDefaultQueue();
        TaskHandle task = queue.add(withUrl(path)
            .payload(request.toString())
            .countdownMillis(delay));
       
        // store task information
        DateTime timestamp = DateTime.now().plus(delay);
        GaeTask storedTask = new GaeTask(task.getName(),
            agentId, timestamp.toString());
        ObjectDatastore datastore = new AnnotationObjectDatastore();
        datastore.store(storedTask);
       
        return task.getName();     
      } catch (MalformedURLException e) {
        e.printStackTrace();
      }

      // TODO: throw error?
      return null;
    }

    /**
     * Cancel a scheduled task by its id
     * @param taskId
     */
    @Override
    public void cancelTask(String id) {
      // stop the task
      Queue queue = QueueFactory.getDefaultQueue();
      queue.deleteTask(id);
     
      // remove stored task
      ObjectDatastore datastore = new AnnotationObjectDatastore();
      GaeTask storedTask = datastore.load(GaeTask.class, id);
      if (storedTask != null) {
        datastore.delete(storedTask);
      }     
    }
   
    /**
     * Get the ids of all currently scheduled tasks
     * @return tasksIds
     */
    @Override
    @Access(AccessType.PUBLIC)
    public Set<String> getTasks() {
      ObjectDatastore datastore = new AnnotationObjectDatastore();
      QueryResultIterator<GaeTask> query = datastore.find()
          .type(GaeTask.class)
          .addFilter("agentId", FilterOperator.EQUAL, agentId).now();
     
      Set<String> taskIds = new HashSet<String>();
      while (query.hasNext()) {
        GaeTask task = query.next();
        if (new DateTime(task.getTimestamp()).isAfterNow()) {
          taskIds.add(task.getTaskId());
        }
        else {
          // clean up expired entry
          datastore.delete(task);
        }
      }
     
      return taskIds;
    }
   
    private String agentId = null;

    @Override
    @Access(AccessType.PUBLIC)
    public Set<String> getDetailedTasks() {
      return getTasks();
    }
  }

  @Override
  public void destroyScheduler(String agentId) {
    // TODO
    //How?
  }
}
TOP

Related Classes of com.almende.eve.scheduler.google.GaeSchedulerFactory$AppEngineScheduler

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.