Skip to content

Commit b5dba22

Browse files
authored
fix: Use async configuration and run on main queue (#28)
* fix: Build docker image for Swift 5.8 * Update ci.yml * Update ci.yml * feat: use async configuration * Update ci.yml
1 parent 5e25793 commit b5dba22

File tree

9 files changed

+81
-64
lines changed

9 files changed

+81
-64
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ RUN swift build -c release --static-swift-stdlib
2929
WORKDIR /staging
3030

3131
# Copy main executable to staging area
32-
RUN cp "$(swift build --package-path /build -c release --show-bin-path)/Run" ./
32+
RUN cp "$(swift build --package-path /build -c release --show-bin-path)/App" ./
3333

3434
# Copy resources bundled by SPM to staging area
3535
RUN find -L "$(swift build --package-path /build -c release --show-bin-path)/" -regex '.*\.resources$' -exec cp -Ra {} ./ \;
@@ -72,5 +72,5 @@ USER vapor:vapor
7272
EXPOSE 8081
7373

7474
# Start the Vapor service when the image is run, default to listening on 8081 in production environment
75-
ENTRYPOINT ["./Run"]
75+
ENTRYPOINT ["./App"]
7676
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8081"]

Package.resolved

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
"kind" : "remoteSourceControl",
4242
"location" : "https://github.com/netreconlab/Parse-Swift.git",
4343
"state" : {
44-
"revision" : "7a0540c9a1f7a2d60f52c50a09b1e8911a7d9ad5",
45-
"version" : "5.5.0"
44+
"revision" : "8e8a84725ed69fe6ec1302f3d9d18018deb0b914",
45+
"version" : "5.5.1"
4646
}
4747
},
4848
{

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ let package = Package(
1616
dependencies: [
1717
.package(url: "https://github.com/vapor/vapor.git", .upToNextMajor(from: "4.76.0")),
1818
.package(url: "https://github.com/netreconlab/Parse-Swift.git",
19-
.upToNextMajor(from: "5.5.0")),
19+
.upToNextMajor(from: "5.5.1")),
2020
],
2121
targets: [
2222
.target(
@@ -25,7 +25,7 @@ let package = Package(
2525
.product(name: "Vapor", package: "vapor"),
2626
.product(name: "ParseSwift", package: "Parse-Swift")
2727
]),
28-
.executableTarget(name: "Run",
28+
.executableTarget(name: "App",
2929
dependencies: [.target(name: "ParseServerSwift")],
3030
swiftSettings: [
3131
// Enable better optimizations when building in Release configuration. Despite the use of

Sources/App/entrypoint.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// entrypoint.swift
3+
//
4+
//
5+
// Created by Corey Baker on 5/11/23.
6+
//
7+
8+
import Vapor
9+
import Dispatch
10+
import Logging
11+
import ParseServerSwift
12+
13+
/// This extension is temporary and can be removed once Vapor gets this support.
14+
private extension Vapor.Application {
15+
static let baseExecutionQueue = DispatchQueue(label: "vapor.codes.entrypoint")
16+
17+
func runFromAsyncMainEntrypoint() async throws {
18+
try await withCheckedThrowingContinuation { continuation in
19+
Vapor.Application.baseExecutionQueue.async { [self] in
20+
do {
21+
try self.run()
22+
continuation.resume()
23+
} catch {
24+
continuation.resume(throwing: error)
25+
}
26+
}
27+
}
28+
}
29+
}
30+
31+
@main
32+
enum Entrypoint {
33+
static func main() async throws {
34+
var env = try Environment.detect()
35+
try LoggingSystem.bootstrap(from: &env)
36+
37+
let app = Application(env)
38+
defer { app.shutdown() }
39+
40+
try await configure(app)
41+
try await app.runFromAsyncMainEntrypoint()
42+
}
43+
}

Sources/ParseServerSwift/ParseServer.swift renamed to Sources/ParseServerSwift/Parse.swift

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import ParseSwift
1010

1111
// MARK: Internal
1212

13-
internal struct ParseServer {
13+
internal struct Parse {
1414
static var configuration: ParseServerConfiguration!
1515
}
1616

1717
/// The current `ParseServerConfiguration` for ParseServerSwift.
1818
public var configuration: ParseServerConfiguration {
19-
ParseServer.configuration
19+
Parse.configuration
2020
}
2121

2222
/**
@@ -31,20 +31,20 @@ public var configuration: ParseServerConfiguration {
3131
- warning: Be sure to call this method before calling `try routes(app)`.
3232
*/
3333
public func initialize(_ configuration: ParseServerConfiguration,
34-
app: Application) throws {
35-
try initializeServer(configuration, app: app)
34+
app: Application) async throws {
35+
try await initializeServer(configuration, app: app)
3636
}
3737

3838
func initialize(_ configuration: ParseServerConfiguration,
3939
app: Application,
40-
testing: Bool) throws {
40+
testing: Bool) async throws {
4141
var configuration = configuration
4242
configuration.isTesting = testing
43-
try initialize(configuration, app: app)
43+
try await initialize(configuration, app: app)
4444
}
4545

4646
func initializeServer(_ configuration: ParseServerConfiguration,
47-
app: Application) throws {
47+
app: Application) async throws {
4848

4949
// Parse uses tailored encoders/decoders. These can be retrieved from any ParseObject
5050
ContentConfiguration.global.use(encoder: User.getJSONEncoder(), for: .json)
@@ -57,26 +57,24 @@ func initializeServer(_ configuration: ParseServerConfiguration,
5757

5858
if !configuration.isTesting {
5959
try setConfiguration(configuration)
60-
Task {
61-
do {
62-
// Initialize the Parse-Swift SDK. Add any additional parameters you need
63-
try await ParseSwift.initialize(applicationId: configuration.applicationId,
64-
primaryKey: configuration.primaryKey,
65-
serverURL: parseServerURL,
66-
// POST all queries instead of using GET.
67-
usingPostForQuery: true,
68-
// Do not use cache for anything.
69-
requestCachePolicy: .reloadIgnoringLocalCacheData) { _, completionHandler in
70-
// Setup to use default certificate pinning. See Parse-Swift docs for more info
71-
completionHandler(.performDefaultHandling, nil)
72-
}
73-
// Check the health of all Parse-Server
74-
try await checkServerHealth()
75-
} catch {
76-
app.shutdown()
60+
do {
61+
// Initialize the Parse-Swift SDK. Add any additional parameters you need
62+
try await ParseSwift.initialize(applicationId: configuration.applicationId,
63+
primaryKey: configuration.primaryKey,
64+
serverURL: parseServerURL,
65+
// POST all queries instead of using GET.
66+
usingPostForQuery: true,
67+
// Do not use cache for anything.
68+
requestCachePolicy: .reloadIgnoringLocalCacheData) { _, completionHandler in
69+
// Setup to use default certificate pinning. See Parse-Swift docs for more info
70+
completionHandler(.performDefaultHandling, nil)
7771
}
72+
// Check the health of all Parse-Server
73+
try await checkServerHealth()
74+
} catch {
75+
app.shutdown()
7876
}
7977
} else {
80-
ParseServer.configuration = configuration
78+
Parse.configuration = configuration
8179
}
8280
}

Sources/ParseServerSwift/Utility/Functions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ import Vapor
2020
if the configuration is already set.
2121
*/
2222
public func setConfiguration(_ configuration: ParseServerConfiguration) throws {
23-
guard ParseServer.configuration == nil else {
23+
guard Parse.configuration == nil else {
2424
throw ParseError(code: .otherCause,
2525
message: "The configuration has already been initialized")
2626
}
27-
ParseServer.configuration = configuration
27+
Parse.configuration = configuration
2828
}
2929

3030
/**
@@ -79,7 +79,7 @@ public func buildServerPathname(_ path: [PathComponent]) throws -> URL {
7979
public func checkServerHealth() async throws {
8080
for parseServerURLString in configuration.parseServerURLStrings {
8181
do {
82-
let serverHealth = try await ParseHealth.check(options: [.serverURL(parseServerURLString)])
82+
let serverHealth = try await ParseServer.health(options: [.serverURL(parseServerURLString)])
8383
configuration.logger.notice("Parse Server (\(parseServerURLString)) health is \"\(serverHealth)\"")
8484
} catch {
8585
configuration.logger.error("Could not connect to Parse Server (\(parseServerURLString)): \(error)")

Sources/ParseServerSwift/configure.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Vapor
22

3-
public func configure(_ app: Application) throws {
3+
public func configure(_ app: Application) async throws {
44
// Initialize ParseServerSwift
55
let configuration = try ParseServerConfiguration(app: app)
6-
try ParseServerSwift.initialize(configuration, app: app)
6+
try await ParseServerSwift.initialize(configuration, app: app)
77

88
// register routes
99
try routes(app)

Sources/Run/main.swift

Lines changed: 0 additions & 24 deletions
This file was deleted.

Tests/ParseServerSwiftTests/AppTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ final class AppTests: XCTestCase {
1818
primaryKey: "primaryKey",
1919
webhookKey: hookKey,
2020
parseServerURLString: "primaryKey")
21-
try ParseServerSwift.initialize(configuration, app: app, testing: true)
21+
try await ParseServerSwift.initialize(configuration, app: app, testing: true)
2222
guard let parseServerURL = URL(string: configuration.primaryParseServerURLString) else {
2323
throw ParseError(code: .otherCause,
2424
message: "Could not make a URL from the Parse Server string")
@@ -167,15 +167,15 @@ final class AppTests: XCTestCase {
167167
let serverString2 = try serverURLString(uri2, parseServerURLStrings: [urlString])
168168
XCTAssertEqual(serverString2, urlString)
169169

170-
ParseServer.configuration.parseServerURLStrings = ["http://localhost:1337/parse"]
170+
Parse.configuration.parseServerURLStrings = ["http://localhost:1337/parse"]
171171
let serverString3 = try serverURLString(uri,
172172
parseServerURLStrings: configuration.parseServerURLStrings)
173173
XCTAssertEqual(serverString3, configuration.parseServerURLStrings.first)
174174
}
175175

176176
func testMatchServerURLStringThrowsError() async throws {
177177
let app = try await setupAppForTesting()
178-
ParseServer.configuration.parseServerURLStrings.removeAll()
178+
Parse.configuration.parseServerURLStrings.removeAll()
179179
defer { app.shutdown() }
180180
let urlString = "https://parse.com/parse"
181181
let uri = URI(stringLiteral: urlString)
@@ -188,7 +188,7 @@ final class AppTests: XCTestCase {
188188
defer { app.shutdown() }
189189
let installationId = "naw"
190190
let urlString = "https://parse.com/parse"
191-
ParseServer.configuration.parseServerURLStrings.append(urlString)
191+
Parse.configuration.parseServerURLStrings.append(urlString)
192192
let dummyHookRequest = DummyRequest(installationId: installationId, params: .init())
193193
let encoded = try User.getJSONEncoder().encode(dummyHookRequest)
194194
let hookRequest = try User.getDecoder().decode(ParseHookFunctionRequest<User, FooParameters>.self,

0 commit comments

Comments
 (0)