Skip to content

Commit

Permalink
Fixed incorrect AWSCore dependency version in podspec (#191)
Browse files Browse the repository at this point in the history
- Added logging helpers, added logging around mutation queue actions
- AppSyncLog's `message` argument is now an autoclosure
- Removed unused DispatchGroup from send operation
- Removed unused context arg to send
  • Loading branch information
palpatim authored Mar 5, 2019
1 parent 398e165 commit f6691ef
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 128 deletions.
2 changes: 1 addition & 1 deletion AWSAppSync.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.ios.deployment_target = '9.0'
s.swift_version = '4.2'
s.dependency 'AWSCore', '~> 2.8.0'
s.dependency 'AWSCore', '~> 2.9.0'
s.dependency 'SQLite.swift', '0.11.5'
s.dependency 'ReachabilitySwift', '~> 4.3.0'
s.source_files = 'AWSAppSyncClient/AWSAppSync.h', 'AWSAppSyncClient/*.swift', 'AWSAppSyncClient/Internal/*.swift', 'AWSAppSyncClient/Apollo/Sources/Apollo/*.swift', 'AWSAppSyncClient/MQTTSDK/*.{h,m}', 'AWSAppSyncClient/MQTTSDK/MQTTSDK/*.{h,m}', 'AWSAppSyncClient/MQTTSDK/SocketRocket/*.{h,m}', 'AWSAppSyncClient/Internal/*.{h,m}'
Expand Down
4 changes: 4 additions & 0 deletions AWSAppSyncClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
FA1A620C21E6533A00AA54D0 /* AWSAppSyncRetryHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1A620B21E6533A00AA54D0 /* AWSAppSyncRetryHandlerTests.swift */; };
FA2B4598221DDF2C00F68E6C /* CachePersistenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2B4597221DDF2C00F68E6C /* CachePersistenceTests.swift */; };
FA2B459A221F436400F68E6C /* MutationQueuePerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2B4599221F436400F68E6C /* MutationQueuePerformanceTests.swift */; };
FA2BE607222746EC0036FCD9 /* AWSAppSyncClientLogFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2BE606222746EC0036FCD9 /* AWSAppSyncClientLogFormatter.swift */; };
FA38636E21DD8FF200DBA2BC /* MutationQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA38636D21DD8FF200DBA2BC /* MutationQueueTests.swift */; };
FA3E128121D5259800F2D19A /* AWSAppSyncClientConfigurationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA3E128021D5259800F2D19A /* AWSAppSyncClientConfigurationError.swift */; };
FA3E128321D5290900F2D19A /* AWSAppSyncClientInfoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA3E128221D5290900F2D19A /* AWSAppSyncClientInfoError.swift */; };
Expand Down Expand Up @@ -446,6 +447,7 @@
FA1A620B21E6533A00AA54D0 /* AWSAppSyncRetryHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSAppSyncRetryHandlerTests.swift; sourceTree = "<group>"; };
FA2B4597221DDF2C00F68E6C /* CachePersistenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachePersistenceTests.swift; sourceTree = "<group>"; };
FA2B4599221F436400F68E6C /* MutationQueuePerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutationQueuePerformanceTests.swift; sourceTree = "<group>"; };
FA2BE606222746EC0036FCD9 /* AWSAppSyncClientLogFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSAppSyncClientLogFormatter.swift; sourceTree = "<group>"; };
FA30F363219B353800B92938 /* SubscriptionStressTestHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionStressTestHelper.swift; sourceTree = "<group>"; };
FA38636D21DD8FF200DBA2BC /* MutationQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutationQueueTests.swift; sourceTree = "<group>"; };
FA3E128021D5259800F2D19A /* AWSAppSyncClientConfigurationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSAppSyncClientConfigurationError.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -767,6 +769,7 @@
CCEF79DC21DE7EED004AD64D /* AWSAppSyncClientError.swift */,
FABD707222050FD100C99B47 /* AWSAppSyncClientInfo.swift */,
FA3E128221D5290900F2D19A /* AWSAppSyncClientInfoError.swift */,
FA2BE606222746EC0036FCD9 /* AWSAppSyncClientLogFormatter.swift */,
178B31051FCDB34100EA4619 /* AWSAppSyncClientS3ObjectsExtensions.swift */,
FA88834421E3C2D300DEBCB3 /* AWSAppSyncConnection.swift */,
17915B041F5F106600C4B73C /* AWSAppSyncHTTPNetworkTransport.swift */,
Expand Down Expand Up @@ -1527,6 +1530,7 @@
17E009C01FCAB234005031DB /* InMemoryNormalizedCache.swift in Sources */,
CC96F8AB21BAF68300446EBD /* AWSRequestBuilder.swift in Sources */,
17E009CA1FCAB234005031DB /* GraphQLExecutor.swift in Sources */,
FA2BE607222746EC0036FCD9 /* AWSAppSyncClientLogFormatter.swift in Sources */,
17E009DC1FCAB234005031DB /* ApolloClient.swift in Sources */,
17E009CE1FCAB234005031DB /* GraphQLError.swift in Sources */,
17D2C2071F6F44A3006C6818 /* AWSOfflineMutation.swift in Sources */,
Expand Down
6 changes: 5 additions & 1 deletion AWSAppSyncClient/AWSAppSyncClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public class AWSAppSyncClient {

init(appSyncConfig: AWSAppSyncClientConfiguration,
reachabilityFactory: NetworkReachabilityProvidingFactory.Type? = nil) throws {

AppSyncLog.info("Initializing AppSyncClient")

self.autoSubmitOfflineMutations = appSyncConfig.autoSubmitOfflineMutations
self.store = appSyncConfig.store
self.appSyncMQTTClient.allowCellularAccess = appSyncConfig.allowsCellularAccess
Expand Down Expand Up @@ -102,6 +105,7 @@ public class AWSAppSyncClient {
}

deinit {
AppSyncLog.info("Releasing AppSyncClient")
NetworkReachabilityNotifier.clearShared()
}

Expand Down Expand Up @@ -132,7 +136,7 @@ public class AWSAppSyncClient {
/// - error: An error that indicates why the fetch failed, or `nil` if the fetch was succesful.
/// - Returns: An object that can be used to cancel an in progress fetch.
@discardableResult public func fetch<Query: GraphQLQuery>(query: Query, cachePolicy: CachePolicy = .returnCacheDataElseFetch, queue: DispatchQueue = DispatchQueue.main, resultHandler: OperationResultHandler<Query>? = nil) -> Cancellable {
AppSyncLog.verbose("fetch: \(query)")
AppSyncLog.verbose("Fetching: \(query)")
return apolloClient!.fetch(query: query, cachePolicy: cachePolicy, queue: queue, resultHandler: resultHandler)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,21 @@ extension AWSAppSyncClient {

func send<Operation: GraphQLMutation>(
operation: Operation,
context: UnsafeMutableRawPointer?,
conflictResolutionBlock: MutationConflictHandler<Operation>?,
dispatchGroup: DispatchGroup?,
handlerQueue: DispatchQueue,
resultHandler: OperationResultHandler<Operation>?) -> Cancellable {

AppSyncLog.verbose("Sending operation \(operation)")

func notifyResultHandler(result: GraphQLResult<Operation.Data>?, error: Error?) {
dispatchGroup?.leave()
guard let resultHandler = resultHandler else { return }

handlerQueue.async {
resultHandler(result, error)
}
}

return self.httpTransport!.send(operation: operation) { (response, error) in
return httpTransport!.send(operation: operation) { (response, error) in
guard let response = response else {
notifyResultHandler(result: nil, error: error)
return
Expand All @@ -61,7 +60,10 @@ extension AWSAppSyncClient {
conflictResolutionBlock(serverState, taskCompletionSource, nil)
taskCompletionSource.task.continueWith(block: { (task) -> Any? in
if let mutation = task.result {
_ = self.send(operation: mutation, context: nil, conflictResolutionBlock: nil, dispatchGroup: dispatchGroup, handlerQueue: handlerQueue, resultHandler: resultHandler)
_ = self.send(operation: mutation,
conflictResolutionBlock: nil,
handlerQueue: handlerQueue,
resultHandler: resultHandler)
}
return nil
}).waitUntilFinished()
Expand All @@ -70,7 +72,7 @@ extension AWSAppSyncClient {
notifyResultHandler(result: result, error: nil)

if let records = records {
self.store?.publish(records: records, context: context).catch { error in
self.store?.publish(records: records).catch { error in
preconditionFailure(String(describing: error))
}
}
Expand Down
47 changes: 47 additions & 0 deletions AWSAppSyncClient/AWSAppSyncClientLogFormatter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Licensed under the Amazon Software License
// http://aws.amazon.com/asl/
//

import Foundation

public final class AWSAppSyncClientLogFormatter: NSObject, AWSDDLogFormatter {

static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
// 2019-02-27 15:09:34.624-0800
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSZ"
return dateFormatter
}()

public func format(message logMessage: AWSDDLogMessage) -> String? {
let logLevelPrefix: String
switch logMessage.flag {
case .error:
logLevelPrefix = "E"
case .warning:
logLevelPrefix = "W"
case .info:
logLevelPrefix = "I"
case .debug:
logLevelPrefix = "D"
default:
logLevelPrefix = "V"
}

let date = AWSAppSyncClientLogFormatter.dateFormatter.string(from: logMessage.timestamp)
let file = AWSDDExtractFileNameWithoutExtension(logMessage.file, false) ?? "(no file)"
let line = String(describing: logMessage.line)

var sourceSection = file
if let function = logMessage.function {
sourceSection += ".\(function)"
}
sourceSection += ", L\(line)"

let message = "\(date) [\(logLevelPrefix) \(sourceSection)] \(logMessage.message)"
return message
}

}
4 changes: 0 additions & 4 deletions AWSAppSyncClient/AWSAppSyncClientS3ObjectsExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@ extension AWSAppSyncClient {
operation: Operation,
s3Object: InternalS3ObjectDetails,
conflictResolutionBlock: MutationConflictHandler<Operation>?,
dispatchGroup: DispatchGroup?,
handlerQueue: DispatchQueue,
resultHandler: OperationResultHandler<Operation>?) {

s3ObjectManager!.upload(s3Object: s3Object) { success, error in
if success {
_ = self.send(
operation: operation,
context: nil,
conflictResolutionBlock: conflictResolutionBlock,
dispatchGroup: dispatchGroup,
handlerQueue: handlerQueue,
resultHandler: resultHandler)
} else {
Expand All @@ -33,7 +30,6 @@ extension AWSAppSyncClient {
func performMutationWithS3Object(
data: Data,
s3Object: InternalS3ObjectDetails,
dispatchGroup: DispatchGroup?,
resultHandler: ((JSONObject?, Error?) -> Void)?) {

s3ObjectManager!.upload(s3Object: s3Object) { success, error in
Expand Down
2 changes: 1 addition & 1 deletion AWSAppSyncClient/Apollo/Sources/Apollo/Record.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public struct Record {
self.key = key
self.fields = fields
}

public subscript(key: CacheKey) -> Value? {
get {
return fields[key]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ final class AWSSubscriptionMetaDataCache {
private let lastSyncDate = Expression<Date?>("lastSyncDate")

init(fileURL: URL) throws {
AppSyncLog.verbose("Initializing subscription metadata cache at \(fileURL.absoluteString)")
db = try Connection(.uri(fileURL.absoluteString), readonly: false)
db.busyTimeout = sqlBusyTimeoutConstant
try createTableIfNeeded()
Expand Down
64 changes: 33 additions & 31 deletions AWSAppSyncClient/Internal/AWSMutationCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import Foundation
import SQLite

/// Although this class is currently public, it is not intended to be used by clients, and will be marked "internal" in
/// a future release of AppSync.
public final class AWSMutationCache {

private let db: Connection
Expand All @@ -22,9 +24,9 @@ public final class AWSMutationCache {
private let s3LocalUri = Expression<String?>("s3LocalUri")
private let s3MimeType = Expression<String?>("s3MimeType")
private let operationString = Expression<String>("operationString")
private let priority = Expression<Int?>("priority")

public init(fileURL: URL) throws {
AppSyncLog.verbose("Initializing mutation cache at \(fileURL.absoluteString)")
db = try Connection(.uri(fileURL.absoluteString), readonly: false)
db.busyTimeout = sqlBusyTimeoutConstant
try createTableIfNeeded()
Expand All @@ -45,57 +47,56 @@ public final class AWSMutationCache {
table.column(operationString)
})

do {
try db.run(mutationRecords.addColumn(priority))
} catch {}

try db.run(mutationRecords.createIndex(recordIdentifier, unique: true, ifNotExists: true))
}

internal func saveMutationRecord(record: AWSAppSyncMutationRecord) -> Promise<Void> {
return Promise {
if let s3Object = record.s3ObjectInput {
let insert = mutationRecords.insert(
recordIdentifier <- record.recordIdentitifer,
data <- record.data!,
recordState <- record.recordState.rawValue,
timestamp <- record.timestamp,
s3Bucket <- s3Object.bucket,
s3Key <- s3Object.key,
s3Region <- s3Object.region,
s3LocalUri <- s3Object.localUri,
s3MimeType <- s3Object.mimeType,
operationString <- record.operationString!)
try db.run(insert)
} else {
let insert = mutationRecords.insert(
recordIdentifier <- record.recordIdentitifer,
data <- record.data!,
recordState <- record.recordState.rawValue,
timestamp <- record.timestamp,
operationString <- record.operationString!)
try db.run(insert)
}
AppSyncLog.verbose("\(record.recordIdentifier): saving")
if let s3Object = record.s3ObjectInput {
let insert = mutationRecords.insert(
recordIdentifier <- record.recordIdentifier,
data <- record.data!,
recordState <- record.recordState.rawValue,
timestamp <- record.timestamp,
s3Bucket <- s3Object.bucket,
s3Key <- s3Object.key,
s3Region <- s3Object.region,
s3LocalUri <- s3Object.localUri,
s3MimeType <- s3Object.mimeType,
operationString <- record.operationString!)
try db.run(insert)
} else {
let insert = mutationRecords.insert(
recordIdentifier <- record.recordIdentifier,
data <- record.data!,
recordState <- record.recordState.rawValue,
timestamp <- record.timestamp,
operationString <- record.operationString!)
try db.run(insert)
}
}
}

internal func updateMutationRecord(record: AWSAppSyncMutationRecord) -> Promise<Void> {
return Promise {
let sqlRecord = mutationRecords.filter(recordIdentifier == record.recordIdentitifer)
AppSyncLog.verbose("\(record.recordIdentifier): updating state \(record.recordState.rawValue)")
let sqlRecord = mutationRecords.filter(recordIdentifier == record.recordIdentifier)
try db.run(sqlRecord.update(recordState <- record.recordState.rawValue))
}
}

internal func deleteMutationRecord(withIdentifier identifier: String) -> Promise<Void> {
return Promise {
AppSyncLog.verbose("Deleting \(identifier)")
AppSyncLog.verbose("\(identifier): deleting")
let sqlRecord = mutationRecords.filter(recordIdentifier == identifier)
try db.run(sqlRecord.delete())
}
}

internal func getStoredMutationRecordsInQueue() -> Promise<[AWSAppSyncMutationRecord]> {
return Promise {
AppSyncLog.info("Retrieving stored mutation records")
let sqlRecords = mutationRecords.filter(recordState == MutationRecordState.inQueue.rawValue).order(timestamp.asc)
var mutationRecordQueue: [AWSAppSyncMutationRecord] = []
for record in try db.prepare(sqlRecords) {
Expand Down Expand Up @@ -123,15 +124,16 @@ public final class AWSMutationCache {
localUri: localUri)
}
} catch {
AppSyncLog.error("\(#function) failed \(error)")
AppSyncLog.error("Failed to retrieve S3Object from mutation record \(mutationRecord.recordIdentifier): \(error)")
}

mutationRecordQueue.append(mutationRecord)
} catch {
AppSyncLog.error("\(#function) failed \(error)")
AppSyncLog.error("Failed to retrieve stored mutation records: \(error)")
}
}

AppSyncLog.debug("Retrieved \(mutationRecordQueue.count) mutation records from store")
return mutationRecordQueue
}
}
Expand Down
8 changes: 4 additions & 4 deletions AWSAppSyncClient/Internal/AWSOfflineMutation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ final class AWSAppSyncMutationRecord {
var jsonRecord: JSONObject?
var data: Data?
var contentMap: GraphQLMap?
var recordIdentitifer: String
var recordIdentifier: String
var recordState: MutationRecordState = .inQueue
var timestamp: Date
var type: MutationType
Expand All @@ -21,7 +21,7 @@ final class AWSAppSyncMutationRecord {
recordIdentifier: String = UUID().uuidString,
timestamp: Date = Date(),
type: MutationType = .graphQLMutation) {
self.recordIdentitifer = recordIdentifier
self.recordIdentifier = recordIdentifier
self.timestamp = timestamp
self.type = type
}
Expand All @@ -32,8 +32,8 @@ final class AWSAppSyncMutationRecord {
extension AWSAppSyncMutationRecord: CustomStringConvertible {

var description: String {
var desc: String = "<\(self):\(recordIdentitifer)"
desc.append("\tID: \(recordIdentitifer)")
var desc: String = "<\(self):\(recordIdentifier)"
desc.append("\tID: \(recordIdentifier)")
desc.append("\ttimestamp: \(timestamp)")
desc.append("\thasS3Object: \(s3ObjectInput != nil ? true : false)")
desc.append(">")
Expand Down
Loading

0 comments on commit f6691ef

Please sign in to comment.