Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 33e43ac

Browse files
committedApr 8, 2016
refactor(double-check-callback): add keep flow and keep ahead for status update, guarantee the status callback in 'restart from low memory' or 'filedownloader process killed and restarted' can be handled more robust
1 parent bb23e59 commit 33e43ac

File tree

3 files changed

+157
-74
lines changed

3 files changed

+157
-74
lines changed
 

‎library/src/main/java/com/liulishuo/filedownloader/BaseDownloadTask.java

Lines changed: 27 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -771,52 +771,51 @@ void over() {
771771
}
772772
}
773773

774-
private void printNotMatchReasonLog(int status) {
775-
if (FileDownloadLog.NEED_LOG) {
776-
FileDownloadLog.d(this, "can't update status change, %d, but the current" +
777-
" status is %d, %d", status, getStatus(), getDownloadId());
774+
boolean updateKeepFlow(final FileDownloadTransferModel transfer) {
775+
if (!FileDownloadStatus.isKeepFlow(getStatus(), transfer.getStatus())) {
776+
if (FileDownloadLog.NEED_LOG) {
777+
FileDownloadLog.d(this, "can't update status change by keep flow, %d, but the" +
778+
" current status is %d, %d", status, getStatus(), getDownloadId());
779+
}
780+
return false;
778781
}
782+
783+
update(transfer);
784+
return true;
785+
}
786+
787+
boolean updateKeepAhead(final FileDownloadTransferModel transfer) {
788+
if (!FileDownloadStatus.isKeepAhead(getStatus(), transfer.getStatus())) {
789+
if (FileDownloadLog.NEED_LOG) {
790+
FileDownloadLog.d(this, "can't update status change by keep ahead, %d, but the" +
791+
" current status is %d, %d", status, getStatus(), getDownloadId());
792+
}
793+
return false;
794+
}
795+
796+
update(transfer);
797+
return true;
779798
}
780799

781800
/**
782801
* @param transfer In order to optimize some of the data in some cases is not back
783802
*/
784-
boolean update(final FileDownloadTransferModel transfer) {
785-
boolean match = false;
803+
private void update(final FileDownloadTransferModel transfer) {
804+
setStatus(transfer.getStatus());
805+
786806
switch (transfer.getStatus()) {
787807
case FileDownloadStatus.pending:
788-
if (getStatus() != FileDownloadStatus.INVALID_STATUS) {
789-
printNotMatchReasonLog(transfer.getStatus());
790-
break;
791-
}
792-
match = true;
793-
this.setStatus(transfer.getStatus());
794808
this.setSoFarBytes(transfer.getSoFarBytes());
795809
this.setTotalBytes(transfer.getTotalBytes());
796810

797811
// notify
798812
getDriver().notifyPending();
799813
break;
800814
case FileDownloadStatus.started:
801-
if (getStatus() != FileDownloadStatus.pending) {
802-
printNotMatchReasonLog(transfer.getStatus());
803-
break;
804-
}
805-
match = true;
806-
this.setStatus(transfer.getStatus());
807-
808815
// notify
809816
getDriver().notifyStarted();
810817
break;
811818
case FileDownloadStatus.connected:
812-
if (getStatus() != FileDownloadStatus.retry &&
813-
getStatus() != FileDownloadStatus.started) {
814-
printNotMatchReasonLog(transfer.getStatus());
815-
break;
816-
}
817-
818-
match = true;
819-
setStatus(transfer.getStatus());
820819
setTotalBytes(transfer.getTotalBytes());
821820
setSoFarBytes(transfer.getSoFarBytes());
822821
this.resuming = transfer.isResuming();
@@ -826,14 +825,6 @@ boolean update(final FileDownloadTransferModel transfer) {
826825
getDriver().notifyConnected();
827826
break;
828827
case FileDownloadStatus.progress:
829-
if (getStatus() != FileDownloadStatus.progress &&
830-
getStatus() != FileDownloadStatus.connected) {
831-
printNotMatchReasonLog(transfer.getStatus());
832-
break;
833-
}
834-
835-
match = true;
836-
setStatus(transfer.getStatus());
837828
setSoFarBytes(transfer.getSoFarBytes());
838829

839830
// notify
@@ -845,15 +836,6 @@ boolean update(final FileDownloadTransferModel transfer) {
845836
*/
846837
break;
847838
case FileDownloadStatus.retry:
848-
if (getStatus() != FileDownloadStatus.progress &&
849-
getStatus() != FileDownloadStatus.pending &&
850-
getStatus() != FileDownloadStatus.connected) {
851-
printNotMatchReasonLog(transfer.getStatus());
852-
break;
853-
}
854-
855-
match = true;
856-
setStatus(transfer.getStatus());
857839
setSoFarBytes(transfer.getSoFarBytes());
858840
setEx(transfer.getThrowable());
859841
_setRetryingTimes(transfer.getRetryingTimes());
@@ -862,14 +844,6 @@ boolean update(final FileDownloadTransferModel transfer) {
862844
getDriver().notifyRetry();
863845
break;
864846
case FileDownloadStatus.error:
865-
if (getStatus() == FileDownloadStatus.error) {
866-
FileDownloadLog.w(this, "%d already err(%s) , callback by other status same transfer",
867-
getDownloadId(), getEx());
868-
break;
869-
}
870-
871-
match = true;
872-
setStatus(transfer.getStatus());
873847
setEx(transfer.getThrowable());
874848
setSoFarBytes(transfer.getSoFarBytes());
875849

@@ -883,16 +857,7 @@ boolean update(final FileDownloadTransferModel transfer) {
883857
*/
884858
break;
885859
case FileDownloadStatus.completed:
886-
if (getStatus() != FileDownloadStatus.INVALID_STATUS &&
887-
getStatus() != FileDownloadStatus.connected &&
888-
getStatus() != FileDownloadStatus.progress) {
889-
printNotMatchReasonLog(transfer.getStatus());
890-
break;
891-
}
892-
893-
match = true;
894860
this.isReusedOldFile = transfer.isReusedOldFile();
895-
setStatus(transfer.getStatus());
896861
// only carry total data back
897862
setSoFarBytes(transfer.getTotalBytes());
898863
setTotalBytes(transfer.getTotalBytes());
@@ -902,12 +867,6 @@ boolean update(final FileDownloadTransferModel transfer) {
902867

903868
break;
904869
case FileDownloadStatus.warn:
905-
if (getStatus() != FileDownloadStatus.INVALID_STATUS) {
906-
printNotMatchReasonLog(transfer.getStatus());
907-
break;
908-
}
909-
910-
match = true;
911870
final int count = FileDownloadList.getImpl().count(getDownloadId());
912871
if (count <= 1) {
913872
// 1. this progress kill by sys and relive,
@@ -931,14 +890,10 @@ boolean update(final FileDownloadTransferModel transfer) {
931890

932891
}
933892

934-
setStatus(transfer.getStatus());
935-
936893
// to FileDownloadList
937894
FileDownloadList.getImpl().removeByWarn(this);
938895
break;
939896
}
940-
941-
return match;
942897
}
943898

944899
// why this? thread not safe: update,ready, _start, pause, start which influence of this
@@ -950,7 +905,7 @@ void markAdded2List() {
950905
isMarkedAdded2List = true;
951906
}
952907

953-
void clearMarkAdded2List(){
908+
void clearMarkAdded2List() {
954909
isMarkedAdded2List = false;
955910
}
956911

‎library/src/main/java/com/liulishuo/filedownloader/FileDownloadTask.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,17 @@ public boolean callback(IDownloadEvent event) {
173173
synchronized (updateSync.intern()) {
174174
boolean consumed = false;
175175
for (BaseDownloadTask task : taskList) {
176-
if (task.update(transfer)) {
176+
if (task.updateKeepFlow(transfer)) {
177177
consumed = true;
178178
break;
179179
}
180180
}
181181

182+
if (!consumed && taskList.size() == 1) {
183+
// Cover the most case for restarting from the low memory status.
184+
consumed = taskList.get(0).updateKeepAhead(transfer);
185+
}
186+
182187
if (!consumed) {
183188
String log = "The flow callback did not consumed, id:" + transfer.getDownloadId() + " status:"
184189
+ transfer.getStatus() + " task-count:" + taskList.size();
@@ -187,8 +192,8 @@ public boolean callback(IDownloadEvent event) {
187192
}
188193
FileDownloadLog.w(FileDownloadTask.class, log);
189194
}
190-
}
191195

196+
}
192197

193198
} else {
194199
if (FileDownloadLog.NEED_LOG) {

‎library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadStatus.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@
2020
* Created by Jacksgong on 11/26/15.
2121
*
2222
* @see com.liulishuo.filedownloader.IFileDownloadMessage
23+
* @see <a href="https://raw.githubusercontent.com/lingochamp/FileDownloader/master/art/filedownloadlistener_callback_flow.png">Callback-Flow</a>
2324
*/
2425
public class FileDownloadStatus {
2526
// [-2^7, 2^7 -1]
2627
public final static byte pending = 1;
2728
public final static byte started = 6;
2829
public final static byte connected = 2;
2930
public final static byte progress = 3;
31+
/**
32+
* Just for event
33+
**/
3034
public final static byte blockComplete = 4;
3135
public final static byte retry = 5;
3236
public final static byte error = -1;
@@ -45,4 +49,123 @@ public static boolean isOver(final int status) {
4549
public static boolean isIng(final int status) {
4650
return status >= pending && status <= started;
4751
}
52+
53+
public static boolean isKeepAhead(final int status, final int nextStatus) {
54+
if (status != progress && status == nextStatus) {
55+
return false;
56+
}
57+
58+
if (isOver(status)) {
59+
return false;
60+
}
61+
62+
switch (status) {
63+
case pending:
64+
switch (nextStatus) {
65+
case INVALID_STATUS:
66+
return false;
67+
default:
68+
return true;
69+
}
70+
case started:
71+
switch (nextStatus) {
72+
case INVALID_STATUS:
73+
case pending:
74+
return false;
75+
default:
76+
return true;
77+
}
78+
79+
case connected:
80+
switch (nextStatus) {
81+
case INVALID_STATUS:
82+
case pending:
83+
case started:
84+
return false;
85+
default:
86+
return true;
87+
}
88+
case progress:
89+
switch (nextStatus) {
90+
case INVALID_STATUS:
91+
case pending:
92+
case started:
93+
case connected:
94+
return false;
95+
default:
96+
return true;
97+
}
98+
99+
case retry:
100+
switch (nextStatus) {
101+
case pending:
102+
case started:
103+
return false;
104+
default:
105+
return true;
106+
}
107+
108+
default:
109+
return true;
110+
}
111+
112+
}
113+
114+
public static boolean isKeepFlow(final int status, final int nextStatus) {
115+
if (status != progress && status == nextStatus) {
116+
return false;
117+
}
118+
119+
if (isOver(status)) {
120+
return false;
121+
}
122+
123+
if (nextStatus == paused) {
124+
return true;
125+
}
126+
127+
if (nextStatus == error) {
128+
return true;
129+
}
130+
131+
switch (status) {
132+
case INVALID_STATUS:
133+
switch (nextStatus) {
134+
case pending:
135+
case warn:
136+
case completed:
137+
return true;
138+
default:
139+
return false;
140+
}
141+
case pending:
142+
switch (nextStatus) {
143+
case started:
144+
return true;
145+
default:
146+
return false;
147+
}
148+
case retry:
149+
case started:
150+
switch (nextStatus) {
151+
case connected:
152+
return true;
153+
default:
154+
return false;
155+
}
156+
case connected:
157+
case progress:
158+
switch (nextStatus) {
159+
case progress:
160+
case completed:
161+
case retry:
162+
return true;
163+
default:
164+
return false;
165+
}
166+
default:
167+
return false;
168+
}
169+
170+
}
48171
}

0 commit comments

Comments
 (0)
Failed to load comments.