Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload duration logic #281

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/android/AckDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,36 @@

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import androidx.work.Data;

@Database(entities = {UploadEvent.class}, version = 5)
@Database(entities = {UploadEvent.class}, version = 6)
@TypeConverters(value = {Data.class})
public abstract class AckDatabase extends RoomDatabase {
private static AckDatabase instance;

public static AckDatabase getInstance(final Context context) {
static final Migration MIGRATION_5_6 = new Migration(5, 6) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE upload_events ADD COLUMN uploadDuration INTEGER NOT NULL DEFAULT 0");
database.execSQL("ALTER TABLE upload_events ADD COLUMN startUploadTime INTEGER NOT NULL DEFAULT 0");
database.execSQL("ALTER TABLE upload_events ADD COLUMN endUploadTime INTEGER NOT NULL DEFAULT 0");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
database.execSQL("ALTER TABLE upload_events ADD COLUMN endUploadTime INTEGER NOT NULL DEFAULT 0");
database.execSQL("ALTER TABLE upload_events ADD COLUMN finishUploadTime INTEGER NOT NULL DEFAULT 0");

}
};


public static synchronized AckDatabase getInstance(final Context context) {
if (instance == null) {
instance = Room
.databaseBuilder(context, AckDatabase.class, "cordova-plugin-background-upload.db")
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_5_6)
.build();
}
return instance;
Expand Down
10 changes: 8 additions & 2 deletions src/android/FileTransferBackground.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private void sendProgress(final String id, int progressPercent) {
}
}

private void sendSuccess(final String id, final String response, int statusCode) {
private void sendSuccess(final String id, final String response, int statusCode, long uploadDuration, long uploadStartTime, long uploadEndTime) {
if (response != null && !response.isEmpty()) {
logMessage("eventLabel='Uploader onSuccess' uploadId='" + id + "' response='" + response.substring(0, Math.min(2000, response.length() - 1)) + "'");
} else {
Expand All @@ -95,6 +95,9 @@ private void sendSuccess(final String id, final String response, int statusCode)
.put("state", "UPLOADED")
.put("serverResponse", response)
.put("statusCode", statusCode)
.put("uploadDuration", uploadDuration)
.put("uploadStartTime", uploadStartTime)
.put("uploadEndTime", uploadEndTime)
);
} catch (JSONException e) {
// Can't really happen but just in case
Expand Down Expand Up @@ -412,7 +415,10 @@ private void handleAck(final Data ackData) {
sendSuccess(
ackData.getString(UploadTask.KEY_OUTPUT_ID),
response,
ackData.getInt(UploadTask.KEY_OUTPUT_STATUS_CODE, -1 /* If this is sent, something is really wrong */)
ackData.getInt(UploadTask.KEY_OUTPUT_STATUS_CODE, -1 /* If this is sent, something is really wrong */),
ackData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_DURATION, 0),
ackData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_START_TIME, 0),
ackData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_END_TIME, 0)
);

} else {
Expand Down
31 changes: 31 additions & 0 deletions src/android/UploadEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public class UploadEvent {
@PrimaryKey
@NonNull
private String id;
private long uploadDuration;
private long uploadStartTime;
private long uploadEndTime;


@ColumnInfo(name = "output_data")
@NonNull
Expand All @@ -19,6 +23,9 @@ public class UploadEvent {
public UploadEvent(@NonNull final String id, @NonNull final Data outputData) {
this.id = id;
this.outputData = outputData;
this.uploadDuration = outputData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_DURATION, 0);
this.uploadStartTime = outputData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_START_TIME, 0);
this.uploadEndTime = outputData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_END_TIME, 0);
}

@NonNull
Expand All @@ -30,4 +37,28 @@ public String getId() {
public Data getOutputData() {
return outputData;
}

public long getUploadDuration() {
return uploadDuration;
}

public void setUploadDuration(long uploadDuration) {
this.uploadDuration = uploadDuration;
}

public long getUploadStartTime() {
return uploadStartTime;
}

public void setUploadStartTime(long uploadStartTime) {
this.uploadStartTime = uploadStartTime;
}

public long getUploadEndTime() {
return uploadEndTime;
}

public void setUploadEndTime(long uploadEndTime) {
this.uploadEndTime = uploadEndTime;
}
}
4 changes: 4 additions & 0 deletions src/android/UploadEventDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

Expand Down Expand Up @@ -32,4 +33,7 @@ default void delete(final String id) {
delete(ack);
}
}

@Update
void update(UploadEvent uploadEvent);
}
16 changes: 15 additions & 1 deletion src/android/UploadTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public final class UploadTask extends Worker {
public static final String KEY_OUTPUT_STATUS_CODE = "output_status_code";
public static final String KEY_OUTPUT_FAILURE_REASON = "output_failure_reason";
public static final String KEY_OUTPUT_FAILURE_CANCELED = "output_failure_canceled";
public static final String KEY_OUTPUT_UPLOAD_DURATION = "output_upload_duration";
public static final String KEY_OUTPUT_UPLOAD_START_TIME = "output_upload_start_time";
public static final String KEY_OUTPUT_UPLOAD_END_TIME = "output_upload_end_time";

// </editor-fold>

private static UploadNotification uploadNotification = null;
Expand All @@ -96,6 +100,9 @@ public void release() { }
private static int concurrency = 1;
private static Semaphore concurrentUploads = new Semaphore(concurrency, true);
private static Mutex concurrencyLock = new Mutex();
private long startUploadTime;
private long endUploadTime;
private long uploadDuration;

public UploadTask(@NonNull Context context, @NonNull WorkerParameters workerParams) {

Expand Down Expand Up @@ -189,6 +196,8 @@ public Result doWork() {
return Result.retry();
}

startUploadTime = System.currentTimeMillis();

// Register me
uploadForegroundNotification.progress(getId(), 0f);
handleNotification();
Expand Down Expand Up @@ -246,6 +255,8 @@ public Result doWork() {
return Result.retry();
}
} finally {
endUploadTime = System.currentTimeMillis();
uploadDuration = endUploadTime - startUploadTime;
// Always remove ourselves from the notification
uploadForegroundNotification.done(getId());
}
Expand All @@ -254,7 +265,10 @@ public Result doWork() {
final Data.Builder outputData = new Data.Builder()
.putString(KEY_OUTPUT_ID, id)
.putBoolean(KEY_OUTPUT_IS_ERROR, false)
.putInt(KEY_OUTPUT_STATUS_CODE, (!DEBUG_SKIP_UPLOAD) ? response.code() : 200);
.putInt(KEY_OUTPUT_STATUS_CODE, (!DEBUG_SKIP_UPLOAD) ? response.code() : 200)
.putLong(KEY_OUTPUT_UPLOAD_DURATION, uploadDuration)
.putLong(KEY_OUTPUT_UPLOAD_START_TIME, startUploadTime)
.putLong(KEY_OUTPUT_UPLOAD_END_TIME, endUploadTime);

// Try read the response body, if any
try {
Expand Down
1 change: 1 addition & 0 deletions src/ios/FileUploader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <Foundation/Foundation.h>
#import "UploadEvent.h"
#import <AFNetworking/AFNetworking.h>
#import <math.h>
NS_ASSUME_NONNULL_BEGIN
@protocol FileUploaderDelegate <NSObject>
@optional
Expand Down
38 changes: 29 additions & 9 deletions src/ios/FileUploader.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "FileUploader.h"
@interface FileUploader()
@property (nonatomic, strong) NSMutableDictionary* responsesData;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDate *> *uploadStartTimes;
@property (nonatomic, strong) NSMutableDictionary *responsesData;
@property (nonatomic, strong) AFURLSessionManager *manager;
@end

Expand All @@ -20,32 +21,48 @@ -(id)init{
return nil;
[UploadEvent setupStorage];
self.responsesData = [[NSMutableDictionary alloc] init];
self.uploadStartTimes = [[NSMutableDictionary alloc] init];
NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[[NSBundle mainBundle] bundleIdentifier]];
configuration.HTTPMaximumConnectionsPerHost = FileUploader.parallelUploadsLimit;
configuration.sessionSendsLaunchEvents = NO;
self.manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
__weak FileUploader *weakSelf = self;
[self.manager setTaskDidCompleteBlock:^(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSError * _Nullable error) {
NSString* uploadId = [NSURLProtocol propertyForKey:kUploadUUIDStrPropertyKey inRequest:task.originalRequest];
NSDate *startTime = weakSelf.uploadStartTimes[uploadId];
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startTime];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format/accuracy is same as android?

NSLog(@"[BackgroundUpload] Task %@ completed with error %@", uploadId, error);
if (!error){
NSData* serverData = weakSelf.responsesData[@(task.taskIdentifier)];
NSString* serverResponse = serverData ? [[NSString alloc] initWithData:serverData encoding:NSUTF8StringEncoding] : @"";
[weakSelf.responsesData removeObjectForKey:@(task.taskIdentifier)];
[weakSelf saveAndSendEvent:@{
@"id" : uploadId,
@"state" : @"UPLOADED",
@"statusCode" : @(((NSHTTPURLResponse *)task.response).statusCode),
@"serverResponse" : serverResponse
}];
if (isnumber(duration)) {
[weakSelf saveAndSendEvent:@{
@"id" : uploadId,
@"state" : @"UPLOADED",
@"statusCode" : @(((NSHTTPURLResponse *)task.response).statusCode),
@"serverResponse" : serverResponse,
@"uploadDuration" : @(duration)
}];
} else {
[weakSelf saveAndSendEvent:@{
@"id" : uploadId,
@"state" : @"UPLOADED",
@"statusCode" : @(((NSHTTPURLResponse *)task.response).statusCode),
@"serverResponse" : serverResponse,
@"uploadDuration" : @"N/A"
}];
}
} else {
[weakSelf.responsesData removeObjectForKey:@(task.taskIdentifier)];
[weakSelf saveAndSendEvent:@{
@"id" : uploadId,
@"state" : @"FAILED",
@"error" : error.localizedDescription,
@"errorCode" : @(error.code)
@"errorCode" : @(error.code),
}];
}
[weakSelf.uploadStartTimes removeObjectForKey:uploadId]; // Clean up
}];

[self.manager setDataTaskDidReceiveDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSData * _Nonnull data) {
Expand All @@ -60,7 +77,7 @@ -(id)init{
}

-(void)saveAndSendEvent:(NSDictionary*)data{
UploadEvent*event = [UploadEvent create:data];
UploadEvent* event = [UploadEvent create:data];
[self sendEvent:[event dataRepresentation]];
}

Expand Down Expand Up @@ -89,6 +106,9 @@ -(void)addUpload:(NSDictionary *)payload completionHandler:(void (^)(NSError* er
completionHandler:^(NSError *error, NSMutableURLRequest *request) {
if (error)
return handler(error);

weakSelf.uploadStartTimes[payload[@"id"]] = [NSDate date];

__block double lastProgressTimeStamp = 0;

[[weakSelf.manager uploadTaskWithRequest:request
Expand Down
Loading