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

xapi.shell.impl.ShellServiceDefault Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
package xapi.shell.impl;

import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import xapi.annotation.inject.InstanceDefault;
import xapi.annotation.inject.SingletonDefault;
import xapi.file.X_File;
import xapi.inject.X_Inject;
import xapi.io.api.LineReader;
import xapi.log.X_Log;
import xapi.shell.api.ShellCommand;
import xapi.shell.api.ShellSession;
import xapi.shell.service.ShellService;
import xapi.time.X_Time;
import xapi.time.api.Moment;
import xapi.util.X_GC;
import xapi.util.api.SuccessHandler;

@InstanceDefault(implFor = ShellService.class)
@SingletonDefault(implFor = ShellService.class)
public class ShellServiceDefault implements ShellService {

  public ShellServiceDefault() {
  }

  @Override
  public ShellCommand newCommand(String ... cmds) {
    return X_Inject.instance(ShellCommand.class).commands(cmds);
  }

  static {
    new Thread() {
      { 
        Runtime.getRuntime().addShutdownHook(this); 
      }
      public void run() {
        while(!runningShells.isEmpty()){
          runningShells.remove().destroy();
        }
      }
    }; 
  }
  
  private static final Queue runningShells = new ConcurrentLinkedQueue<>();

//  private static abstract class ScriptProvider extends SingletonProvider {
//    abstract String getScriptName();
//    public String getScriptLocation() {
//      return X_File.getResourceMaybeUnzip(getScriptName(), Thread.currentThread().getContextClassLoader());
//    }
//  }
  
  @Override
  public ShellSession runInShell(final boolean keepAlive, LineReader stdOut, LineReader stdErr, final String ... cmds) {
    final Moment start = X_Time.now();
    final String[] commands;
    if (keepAlive) {
      final String sh = X_File.unzippedResourcePath("xapi/sh.sh", null);
      commands = new String[]{"sh", "-ac", sh};
    } else {
      commands = cmds;
    }
    final ShellSession runningShell = 
      X_Inject.instance(ShellCommand.class)
        .commands(commands)
        .run(new SuccessHandler() {
            @Override
            public void onSuccess(ShellSession t) {
              X_Log.trace(getClass(), "Shell still running?", t.isRunning());
            }
      }, null);
    X_Log.debug(getClass(), "Time create shell command", X_Time.difference(start));
    if (stdOut != null) {
      runningShell.stdOut(stdOut);
    }
    if (stdErr != null) {
      runningShell.stdErr(stdErr);
    }
    X_Time.runLater(new Runnable() {
      @Override
      public void run() {
        if (keepAlive) {
          for (String cmd : cmds) {
            runningShell.stdIn(cmd);
          }
        }
        X_Log.debug(getClass(), "Time to send shell command", X_Time.difference(start));
        // release thread
        X_Time.trySleep(0, 1000);
        // periodically clean up trash object
        runCleanup();
      }
    });
    return runningShell;
  }

  protected void runCleanup() {
    for (
        Iterator iter = runningShells.iterator();
        iter.hasNext(); ) {
      ShellSession next = iter.next();
      if (!next.isRunning()) {
        X_Log.trace(getClass(), "Recycle shell that is no longer running", next);
        X_GC.destroy(ShellSession.class, next);
        iter.remove();
      }
    }
  }
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy