All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.tree.resume.AsyncExecution Maven / Gradle / Ivy

The newest version!
package org.snapscript.tree.resume;

import java.util.Iterator;

import org.snapscript.core.Execution;
import org.snapscript.core.result.Result;
import org.snapscript.core.resume.Answer;
import org.snapscript.core.resume.Promise;
import org.snapscript.core.resume.PromiseWrapper;
import org.snapscript.core.resume.Task;
import org.snapscript.core.resume.TaskScheduler;
import org.snapscript.core.resume.Yield;
import org.snapscript.core.scope.Scope;

public class AsyncExecution extends Execution {

   private final TaskScheduler scheduler;
   private final PromiseWrapper wrapper;
   private final Execution execution;

   public AsyncExecution(TaskScheduler scheduler, Execution execution) {
      this.wrapper = new PromiseWrapper();
      this.scheduler = scheduler;
      this.execution = execution;
   }

   @Override
   public Result execute(Scope scope) throws Exception {
      Result result = execution.execute(scope);

      if(!result.isAwait()) {
         Object value = result.getValue();
         Promise promise = wrapper.toPromise(scope, value);

         return Result.getNormal(promise);
      }
      return execute(scope, result);
   }

   private Result execute(Scope scope, Result result) throws Exception {
      Yield yield = result.getValue();
      Iterator iterator = yield.iterator();
      Task task = new AnswerTask(iterator);
      Promise promise = scheduler.schedule(scope, task);

      return Result.getNormal(promise);
   }

   private static class AnswerTask implements Task {

      private final Iterator iterator;

      public AnswerTask(Iterator iterator) {
         this.iterator = iterator;
      }

      @Override
      public void execute(Answer answer) {
         Task task = new ResumeTask(iterator, answer);

         try {
            task.execute(null);
         } catch(Throwable cause){
            answer.failure(cause);
         }
      }
   }

   private static class ResumeTask implements Task {

      private final Iterator iterator;
      private final Answer answer;

      public ResumeTask(Iterator iterator, Answer answer) {
         this.iterator = iterator;
         this.answer = answer;
      }

      @Override
      public void execute(Object object) {
         try {
            while (iterator.hasNext()) {
               object = iterator.next();

               if(object != null) {
                  if (Promise.class.isInstance(object)) {
                     Promise promise = (Promise) object;
                     promise.success(this);
                     promise.failure(this);
                     return;
                  }
               }
            }
            answer.success(object);
         } catch(Throwable cause){
            answer.failure(cause);
         }
      }
   }
}