/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2015
*/
package com.ibm.streamsx.topology.function;
import java.net.MalformedURLException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
/**
* Context for a function executing in a IBM Streams application.
*/
public interface FunctionContext {
/**
* Get the container hosting a function
* @return Container hosting a function.
*/
FunctionContainer getContainer();
/**
* Return a scheduler to execute background tasks. Functions should utilize
* this service or {@link #getThreadFactory()} rather than creating their own threads
* to ensure that the SPL runtime will wait for any background work
* before completing an application.
* <P>
* The scheduler will be shutdown when the processing element is to be shutdown.
* Once the scheduler is shutdown no new tasks will be accepted. Existing
* scheduled tasks will remain in the scheduler's queue but periodic tasks
* will canceled.
* <BR>
* Functions that implement {@code AutoCloseable} that wish to complete any outstanding tasks
* at close time can call {@code ExecutorService.awaitTermination()}
* to wait for outstanding tasks to complete or wait on the specific
* {@code Future} reference for a task.
* </P>
*
* <P>
* The returned scheduler service is guaranteed to be an instance
* of {@code java.util.concurrent.ScheduledThreadPoolExecutor}
* and initially has this configuration:
* <UL>
* <LI> {@code corePoolSize} Set to {@code Runtime.availableProcessors()} with
* a minimum of 2 and maximum of 8. </LI>
* <LI> {@code allowsCoreThreadTimeOut()} set to {@code true}</LI>
* <LI> {@code keepAliveTime} set to 5 seconds</LI>
* </UL>
* Threads are created on demand to execute tasks, so that even if the
* {@code corePoolSize} is eight, eight threads will only be created if
* there are eight concurrent tasks scheduled. Threads will be removed
* if they are not needed for the {@code keepAliveTime} value and
* {@code allowsCoreThreadTimeOut()} returns {@code true}.
* </P>
*
* @return Scheduler service that can be used by the function.
* @see "java.util.concurrent.ExecutorService"
* @see "java.util.concurrent.Future"
* @see "java.util.concurrent.ScheduledThreadPoolExecutor"
*/
ScheduledExecutorService getScheduledExecutorService();
/**
* Return a ThreadFactory that can be used by the function with the thread context
* class loader set correctly. Functions should utilize
* the returned factory to create Threads.
* <P>
* Threads returned by the ThreadFactory have not been started
* and are set as daemon threads. Functions may set the threads
* as non-daemon before starting them. The SPL runtime will wait
* for non-daemon threads before terminating a processing
* element in standalone mode.
* </P>
* <P>
* Any uncaught exception thrown by the {@code Runnable} passed
* to the {@code ThreadFactory.newThread(Runnable)} will cause
* the processing element containing the function to terminate.
* </P>
* <P>
* The ThreadFactory will be shutdown when the processing element is to be shutdown.
* Once the ThreadFactory
* is shutdown a call to <code>newThread()</code> will return null.
* </P>
*
* @return A ThreadFactory that can be used by the function.
*/
ThreadFactory getThreadFactory();
/**
* Get the index of the parallel channel the function is on.
* <P>
* If the function is in a parallel region, this method returns a value from
* 0 to N-1, where N is the {@link #getMaxChannels() number of channels in the parallel region};
* otherwise it returns -1.
* </P>
*
* @return the index of the parallel channel if the
* function is executing in a parallel region, or -1 if the function
* is not executing in a parallel region.
*
*/
int getChannel();
/**
* Get the total number of parallel channels for the parallel region that
* the function is in. If the function is not in a parallel region, this
* method returns 0.
*
* @return the number of parallel channels for the parallel region that this
* function is in, or 0 if the function is not in a parallel region.
*/
int getMaxChannels();
/**
* Add class libraries to the functional class loader. The functional
* class loader is set as the thread context class loader for
* {@link #getThreadFactory() thread factory},
* {@link #getScheduledExecutorService() executor} and any method
* invocation on the function instance.
* <P>
* Functions use this method to add class libraries specific
* to the invocation in
* a consistent manner. An example is defining the jar files that
* contain the JDBC driver to be used by the application.
* <P>
* Each element of {@code libraries} is trimmed and then converted
* into a {@code java.net.URL}. If the element cannot be converted
* to a {@code URL} then it is assumed to represent a file system
* path and is converted into an {@code URL} representing that path.
* If the file path is relative the used location is currently
* undefined, thus use of relative paths are not recommended.
* <BR>
* If a file path ends with {@code /* } then it is assumed to
* be a directory and all jar files in the directory
* with the extension {@code .jar} or {@code .JAR} are
* added to the function class loader.
* </P>
*
* @param libraries String representations of URLs and file paths to be
* added into the functional class loader. If {@code null} then no libraries
* are added to the class loader.
*
*/
void addClassLibraries(String[] libraries) throws MalformedURLException;
}