-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
697 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
apply plugin: 'java' | ||
|
||
dependencies { | ||
compile fileTree(dir: 'libs', include: ['*.jar']) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package cn.zhaiyifan.init; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.Callable; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Future; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* <p>A coarse-grained concept, normally an app has only one flow, complex apps can have flow other | ||
* than init flow, like patch, broadcast, etc.</p> | ||
* Created by mark.zhai on 2015/10/2. | ||
*/ | ||
public class Flow { | ||
private static final String TAG = "Flow"; | ||
private static final long DEFAULT_FLOW_TIMEOUT = 3000; | ||
|
||
private Map<Integer, Wave> mWaveMap; | ||
private Map<String, Integer> mTaskToWaveMap; | ||
|
||
private int mFlowStatus = Status.STATUS_UNKNOWN; | ||
|
||
private String mName; | ||
private long mTimeout = DEFAULT_FLOW_TIMEOUT; | ||
private boolean mCancel = false; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param flowName flow name | ||
*/ | ||
public Flow(String flowName) { | ||
mName = flowName; | ||
mFlowStatus = Status.STATUS_PENDING_START; | ||
|
||
mWaveMap = new HashMap<>(); | ||
mTaskToWaveMap = new HashMap<>(); | ||
} | ||
|
||
/** | ||
* Add task to this flow. | ||
* | ||
* @param waveSeq Which wave sequence to add. | ||
* @param task task | ||
* @return Flow | ||
*/ | ||
public Flow addTask(int waveSeq, Task task) { | ||
if (task != null) { | ||
Wave wave = mWaveMap.get(waveSeq); | ||
if (wave == null) { | ||
wave = new Wave(waveSeq, ProcessUtils.myProcessName()); | ||
mWaveMap.put(waveSeq, wave); | ||
} | ||
wave.addTask(task); | ||
mTaskToWaveMap.put(task.getName(), waveSeq); | ||
} | ||
return this; | ||
} | ||
|
||
/** | ||
* Set timeout to this flow. | ||
* | ||
* @param timeout timeout in milliseconds | ||
*/ | ||
public void setTimeout(long timeout) { | ||
mTimeout = timeout; | ||
} | ||
|
||
/** | ||
* Start flow, return when all blocked tasks completed. | ||
*/ | ||
public synchronized void start() { | ||
if (mFlowStatus != Status.STATUS_PENDING_START) { | ||
throw new RuntimeException("Error! Flow has already started."); | ||
} | ||
|
||
long startTime = System.currentTimeMillis(); | ||
|
||
ExecutorService threadPool = Init.getThreadPool(); | ||
|
||
Callable<Boolean> flowTask = new Callable<Boolean>() { | ||
@Override | ||
public Boolean call() throws Exception { | ||
for (Map.Entry<Integer, Wave> entry : mWaveMap.entrySet()) { | ||
if (mCancel) { | ||
return false; | ||
} | ||
Wave wave = entry.getValue(); | ||
wave.start(); | ||
} | ||
return true; | ||
} | ||
}; | ||
|
||
Future<Boolean> initTask = threadPool.submit(flowTask); | ||
|
||
try { | ||
initTask.get(mTimeout, TimeUnit.MILLISECONDS); | ||
} catch (Exception e) { | ||
LogImpl.w(TAG, "timeout for flow: " + getName()); | ||
} | ||
|
||
long endTime = System.currentTimeMillis(); | ||
LogImpl.i(TAG, getName() + " runs " + (endTime - startTime)); | ||
|
||
mFlowStatus = Status.STATUS_EXECUTING; | ||
} | ||
|
||
/** | ||
* cannot guarantee immediately cancel | ||
*/ | ||
public void cancel() { | ||
mCancel = true; | ||
} | ||
|
||
/** | ||
* Get flow status. | ||
* | ||
* @return status | ||
*/ | ||
public int getFlowStatus() { | ||
return mFlowStatus; | ||
} | ||
|
||
/** | ||
* Get task status. | ||
* | ||
* @param taskName task name | ||
* @return status | ||
*/ | ||
public int getTaskStatus(String taskName) { | ||
Integer waveSeq = mTaskToWaveMap.get(taskName); | ||
Wave wave = mWaveMap.get(waveSeq); | ||
if (wave != null) { | ||
return wave.getTaskStatus(taskName); | ||
} else { | ||
return Status.STATUS_UNKNOWN; | ||
} | ||
} | ||
|
||
/** | ||
* Get name of the flow. | ||
* | ||
* @return flow name. | ||
*/ | ||
public String getName() { | ||
return mName; | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
.../main/java/cn/zhaiyifan/appinit/ILog.java → ...src/main/java/cn/zhaiyifan/init/ILog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package cn.zhaiyifan.init; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
/** | ||
* <p>Entry to add, start and manage init flow.</p> | ||
* Created by mark.zhai on 2015/10/2. | ||
*/ | ||
public class Init { | ||
private static final int DEFAULT_THREAD_POOL_SIZE = 8; | ||
|
||
private static Map<String, Flow> sFlowMap = new HashMap<>(); | ||
private static int mThreadPoolSize = DEFAULT_THREAD_POOL_SIZE; | ||
|
||
/** | ||
* Init with context and log class. | ||
* | ||
* @param logProxy log class implements {@link ILog} | ||
*/ | ||
public static void init(ILog logProxy) { | ||
LogImpl.setLogProxy(logProxy); | ||
} | ||
|
||
public static void addFlow(Flow flow) { | ||
sFlowMap.put(flow.getName(), flow); | ||
} | ||
|
||
public static void addFlow(Map<String, Flow> flowMap) { | ||
sFlowMap.putAll(flowMap); | ||
} | ||
|
||
/** | ||
* Set thread pool size used by tasks. | ||
* | ||
* @param size thread pool size, value less or equal than 0 will produce a cached thread pool. | ||
*/ | ||
public static void setThreadPoolSize(int size) { | ||
mThreadPoolSize = size; | ||
} | ||
|
||
public static Flow getFlow(String flowName) { | ||
Flow flow = sFlowMap.get(flowName); | ||
return flow != null ? flow : new Flow(flowName); | ||
} | ||
|
||
/** | ||
* start flow. | ||
* | ||
* @param flowName flow key, should be unique for each flow. | ||
*/ | ||
public static void start(String flowName) { | ||
Flow flow = sFlowMap.get(flowName); | ||
if (flow != null) { | ||
flow.start(); | ||
} | ||
} | ||
|
||
/** | ||
* start flow. | ||
*/ | ||
public static void start(Flow flow) { | ||
flow.start(); | ||
} | ||
|
||
/** | ||
* Cancel the flow. | ||
* | ||
* @param flowName flow key, should be unique for each flow. | ||
*/ | ||
public static void cancel(String flowName) { | ||
Flow flow = sFlowMap.get(flowName); | ||
if (flow != null) { | ||
flow.cancel(); | ||
} | ||
} | ||
|
||
/** | ||
* Get status of flow specified by given name, see {@link Status}. | ||
* | ||
* @param flowName flow key, should be unique for each flow. | ||
* @return flow status in {@code STATUS_UNKNOWN}, {@code STATUS_PENDING_START}, | ||
* {@code STATUS_EXECUTING} and {@code STATUS_DONE}. | ||
*/ | ||
public static int getFlowStatus(String flowName) { | ||
Flow flow = sFlowMap.get(flowName); | ||
return flow != null ? flow.getFlowStatus() : Status.STATUS_UNKNOWN; | ||
} | ||
|
||
/** | ||
* Get thread pool used internally by Init library. | ||
* | ||
* @return thread pool | ||
*/ | ||
public static ExecutorService getThreadPool() { | ||
if (mThreadPoolSize <= 0) { | ||
return Executors.newCachedThreadPool(); | ||
} else { | ||
return Executors.newFixedThreadPool(mThreadPoolSize); | ||
} | ||
} | ||
} |
Oops, something went wrong.