Skip to content

Commit 0b9e04a

Browse files
committed
Added a small swift http server with FlyingFox
1 parent f2172e6 commit 0b9e04a

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import FlyingFox
2+
import Foundation
3+
4+
struct PayloadContent: Codable {
5+
let value: Int
6+
init(value: Int){
7+
self.value = value;
8+
}
9+
}
10+
11+
class DummyServer {
12+
let server : HTTPServer
13+
14+
private func handleRequest(request: HTTPRequest) async -> HTTPResponse{
15+
do {
16+
let bodyStr = try await request.bodyData
17+
let body = try JSONDecoder().decode(PayloadContent.self, from: bodyStr)
18+
let response = "\(body.value)"
19+
if let responseData = response.data(using: .utf8) {
20+
return HTTPResponse(statusCode: .ok, body: responseData)
21+
}
22+
} catch {
23+
print("An unexpected error occurred: \(error)")
24+
}
25+
return HTTPResponse(statusCode: .internalServerError, body: Data("Internal Server Error".utf8))
26+
}
27+
28+
init(_ port: UInt16) async {
29+
server = HTTPServer(port: port)
30+
await server.appendRoute("POST /api") {request in
31+
return await self.handleRequest(request: request)
32+
}
33+
}
34+
35+
func start() async throws {
36+
try await server.start()
37+
}
38+
39+
func stop() async throws{
40+
await server.stop(timeout: 3)
41+
}
42+
}
43+
44+
func send(url: URL, value: Int) async -> Int {
45+
let payload = PayloadContent(value: value)
46+
guard let jsonData = try? JSONEncoder().encode(payload) else { return 0 }
47+
48+
var request = URLRequest(url: url)
49+
request.httpMethod = "POST"
50+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
51+
request.httpBody = jsonData
52+
do {
53+
let (data, _) = try await URLSession.shared.data(for: request)
54+
if let responseStr = String(data: data, encoding: .utf8), let intValue = Int(responseStr) {
55+
return intValue
56+
}
57+
} catch {
58+
print(error)
59+
}
60+
return 0
61+
}
62+
63+
func main()async throws{
64+
print("Hello world!")
65+
// Command line arguments
66+
let args = CommandLine.arguments
67+
var n = 10
68+
69+
if args.count == 2, let inputNumber = Int(args[1]) {
70+
n = inputNumber
71+
}
72+
print(n)
73+
74+
// Generate a random port number in the range 20000 to 50000
75+
let port = UInt16.random(in: 20000...50000)
76+
77+
let task = Task {
78+
let server = await DummyServer(port)
79+
try await server.start()
80+
}
81+
let urlString = "http://localhost:\(port)/api"
82+
83+
guard let url = URL(string: urlString) else {
84+
print("Invalid URL")
85+
exit(1)
86+
}
87+
88+
var sum = 0
89+
90+
await withTaskGroup(of: Int.self) { group in
91+
for i in 1...n {
92+
group.addTask {
93+
await send(url: url, value: i)
94+
}
95+
}
96+
97+
for await result in group {
98+
sum += result
99+
}
100+
}
101+
102+
print(sum)
103+
task.cancel()
104+
105+
}
106+
107+
try await main()

bench/bench_swift.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ problems:
2121
- name: knucleotide
2222
source:
2323
- 2.swift
24+
- name: http-server
25+
source:
26+
- 1.swift
2427
compiler_version_command: swift --version
2528
compiler_version_regex:
2629
runtime_version_parameter:

bench/include/swift/Package.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
// swift-tools-version:5.5
1+
// swift-tools-version:5.7
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "app",
8+
platforms: [
9+
.macOS(.v13)
10+
],
811
dependencies: [
912
// Dependencies declare other packages that this package depends on.
1013
// .package(url: /* package url */, from: "1.0.0"),
11-
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.3.0")
12-
// .package(url: "https://github.com/httpswift/swifter.git", .upToNextMajor(from: "1.5.0"))
14+
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.3.0"),
15+
.package(url: "https://github.com/swhitty/FlyingFox.git", .upToNextMajor(from: "0.15.0"))
1316
],
1417
targets: [
1518
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -18,7 +21,7 @@ let package = Package(
1821
name: "app",
1922
dependencies: [
2023
"BigInt",
21-
// .product(name: "Swifter", package: "swifter")
24+
"FlyingFox",
2225
]),
2326
// .testTarget(
2427
// name: "appTests",

0 commit comments

Comments
 (0)