Permalink
Browse files

Fix/Improve AsyncAction and socket.lookup

  • Loading branch information...
JasonTheKitten committed Jun 18, 2018
1 parent 870060e commit eedd882be4dfbb061210662e273fb225a000991c
@@ -21,6 +21,7 @@
public class SocketAPI implements ILuaAPI, IAsyncObject {
private final IAPIEnvironment m_apiEnvironment;
private final List < Socket > m_socks;
private AsyncAction m_queue;
private String[] methods = {
"open",
@@ -29,9 +30,8 @@
};
public SocketAPI(IAPIEnvironment environment) {
new AsyncAction().startAsyncAction();
m_apiEnvironment = environment;
m_socks = new ArrayList < Socket > ();
m_socks = new ArrayList<Socket>();
}
@Override
@@ -42,13 +42,16 @@ public SocketAPI(IAPIEnvironment environment) {
}
@Override
public void startup() {}
public void startup() {
m_queue = new AsyncAction("async_socket");
}
@Override
public void advance(double _dt) {}
@Override
public void shutdown() {
m_queue.clear();
synchronized(m_socks) {
for (Socket sock: m_socks) {
try {
@@ -57,7 +60,6 @@ public void shutdown() {
}
m_socks.clear();
}
AsyncAction.clear();
}
@Nonnull
@@ -71,7 +73,7 @@ public void shutdown() {
switch (method) {
default: {
int ID = AsyncAction.runAsyncAction(
int ID = m_queue.runAsyncAction(
this, m_apiEnvironment, context, method, args
);
@@ -117,7 +119,7 @@ public void shutdown() {
m_socks.add(sock);
}
return new Object[] {
methods[method], true, SocketWrapper.wrapSocket(sock, certs, m_apiEnvironment)
methods[method], true, SocketWrapper.wrapSocket(sock, certs, m_apiEnvironment, m_queue)
};
}
@@ -134,18 +136,19 @@ public void shutdown() {
};
}
String addr = address.getHostAddress();
URL info = new URL(myURL);
if (info == null) {
info = new URL("http://" + myURL);
}
if (info == null) {
return new Object[] {
methods[method], true, addr
};
}
return new Object[] {
methods[method], true, addr, info.getDefaultPort()
};
URI info = new URI(myURL);
int port = info.getPort();
if (port == -1) {
try {
URL inf = new URL(myURL);
port = inf.getDefaultPort();
} catch (Exception e) {}
}
return new Object[] {
methods[method], true, addr, port, info.getScheme()
};
}
case 2:
@@ -6,66 +6,80 @@
package dan200.computercraft.core.apis.socket;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.*;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaObject;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.apis.socket.IAsyncObject;
public class AsyncAction implements Runnable {
private static final List<AsyncMethod> m_actions = new ArrayList<AsyncMethod>();
public class AsyncAction {
public void startAsyncAction() {
Thread m_thread = new Thread(this);
m_thread.setDaemon(true);
m_thread.start();
}
private List<Future<?>> m_futures;
private ExecutorService threadPool;
private String event_type = "async";
public static int runAsyncAction (IAsyncObject callable, IAPIEnvironment environment, @Nonnull ILuaContext context, int method, @Nonnull Object[] args) {
AsyncMethod meth = new AsyncMethod(callable, environment, context, method, args);
synchronized (m_actions) {
m_actions.add(meth);
}
return meth.ID;
public AsyncAction() {
init();
}
public static void clear() {
synchronized (m_actions) {
m_actions.clear();
}
public AsyncAction(String ev_t) {
event_type = ev_t;
init();
}
public void init() {
threadPool = new ThreadPoolExecutor(
4, 2048,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadFactoryBuilder()
.setDaemon( true )
.setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
.setNameFormat( "ComputerCraft-"+event_type+"-%d" )
.build()
);
m_futures = new ArrayList<Future<?>>();
}
public int runAsyncAction (IAsyncObject callable, IAPIEnvironment environment, @Nonnull ILuaContext context, int method, @Nonnull Object[] args) {
AsyncMethod meth = new AsyncMethod(callable, environment, context, method, args, event_type);
m_futures.add(threadPool.submit(meth));
return meth.ID;
}
public void run() {
while (true) {
synchronized (m_actions) {
Iterator<AsyncMethod> acts = m_actions.iterator();
while (acts.hasNext()) {
AsyncMethod action = acts.next();
action.run();
acts.remove();
}
public void clear() {
synchronized (m_futures) {
for (Future<?> k: m_futures) {
k.cancel( false );
}
m_futures.clear();
}
threadPool.shutdown();
}
}
class AsyncMethod {
class AsyncMethod implements Runnable {
private IAsyncObject m_callable;
private IAPIEnvironment m_environment;
private ILuaContext m_context;
private int m_method;
private Object[] m_args;
private String m_event_type;
public int ID;
public AsyncMethod(IAsyncObject callable, IAPIEnvironment environment, @Nonnull ILuaContext context, int method, @Nonnull Object[] args) {
public AsyncMethod(IAsyncObject callable, IAPIEnvironment environment, @Nonnull ILuaContext context, int method, @Nonnull Object[] args, @Nonnull String event_type) {
m_callable = callable;
m_environment = environment;
m_context = context;
m_method = method;
m_args = args;
m_event_type = event_type;
ID = Counter.value;
Counter.inc();
}
@@ -78,9 +92,9 @@ public void run() {
finalRtn[i + 1] = rtn[i];
};
finalRtn[0] = ID;
m_environment.queueEvent("async_socket", finalRtn);
m_environment.queueEvent(m_event_type, finalRtn);
} catch (Exception e) {
m_environment.queueEvent("async_socket", new Object[] {ID, false, e.getMessage()});
m_environment.queueEvent(m_event_type, new Object[] {ID, false, e.getMessage()});
}
}
@@ -91,7 +105,7 @@ public void run() {
public static int value = 0;
public static void inc() {
if (value == 2147483647) value = -1;
if (value == Integer.MAX_VALUE) value = -1;
value++;
}
@@ -34,7 +34,7 @@
"readAll"
};
public static ILuaObject wrapSocket(final Socket sock, final CertWrapper certs, IAPIEnvironment m_apiEnvironment) {
public static ILuaObject wrapSocket(final Socket sock, final CertWrapper certs, IAPIEnvironment m_apiEnvironment, AsyncAction m_queue) {
class WrappedSocket implements ILuaObject, IAsyncObject {
@@ -49,7 +49,7 @@ public static ILuaObject wrapSocket(final Socket sock, final CertWrapper certs,
switch (method) {
default: {
int ID = AsyncAction.runAsyncAction(
int ID = m_queue.runAsyncAction(
this, m_apiEnvironment, context, method, args
);
@@ -1,5 +1,5 @@
The functions included in the socket API are as follows:
host, port = socket.lookup(uri) --Returns the values required for socket.open
host, port, scheme = socket.lookup(uri) --Returns the values required for socket.open. If scheme is not recognized, port will be -1
sock = socket.open(host, port, useSSL) --Returns a socket. Note that the host must be an IP address, which can be found with socket.lookup()
socket.checkHost(host) --Basically http.checkURL, but with URIs

0 comments on commit eedd882

Please sign in to comment.