Skip to content
12 changes: 6 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ let package = Package(
],
products: [
.library(
name: "SwiftMemcache",
targets: ["SwiftMemcache"]
name: "Memcache",
targets: ["Memcache"]
),
],
dependencies: [
Expand All @@ -36,7 +36,7 @@ let package = Package(
],
targets: [
.target(
name: "SwiftMemcache",
name: "Memcache",
dependencies: [
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOPosix", package: "swift-nio"),
Expand All @@ -47,12 +47,12 @@ let package = Package(
),
.testTarget(
name: "SwiftMemcacheTests",
dependencies: ["SwiftMemcache"]
dependencies: ["Memcache"]
),
.executableTarget(
name: "swift-memcache-gsoc-example",
name: "MemcacheExample",
dependencies: [
.target(name: "SwiftMemcache"),
.target(name: "Memcache"),
]
),
]
Expand Down
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,61 @@
SwiftMemcache is a Swift Package in development that provides a convenient way to communicate with [Memcached](https://github.com/memcached/memcached) servers.

## Getting Started

## Overview

### Memcache Connection API

Our `MemcacheConnection` allows for communicate with a Memcached server. This actor takes care of establishing a connection, creating a request stream and handling asynchronous execution of commands.

Here's an example of how you can use `MemcachedConnection` in a program.

```swift
@main
struct Program {
// Use the shared singleton instance of MultiThreadedEventLoopGroup
static let eventLoopGroup = MultiThreadedEventLoopGroup.singleton
// Initialize the logger
static let logger = Logger(label: "memcache")

static func main() async throws {
// Instantiate a new MemcacheConnection actor with host, port, and event loop group
let memcacheConnection = MemcacheConnection(host: "127.0.0.1", port: 11211, eventLoopGroup: eventLoopGroup)

// Initialize the service group
let serviceGroup = ServiceGroup(services: [memcacheConnection], logger: self.logger)

try await withThrowingTaskGroup(of: Void.self) { group in
// Add the connection actor's run function to the task group
// This opens the connection and handles requests until the task is cancelled or the connection is closed
group.addTask { try await serviceGroup.run() }

// Set a value for a key.
let setValue = "bar"
try await memcacheConnection.set("foo", value: setValue)

// Get the value for a key.
// Specify the expected type for the value returned from Memcache.
let getValue: String? = try await memcacheConnection.get("foo")

// Assert that the get operation was successful by comparing the value set and the value returned from Memcache.
// If they are not equal, this will throw an error.
assert(getValue == setValue, "Value retrieved from Memcache does not match the set value")

// Cancel all tasks in the task group.
// This also results in the connection to Memcache being closed.
group.cancelAll()
}
}
}
```

## Contributing

### Docker

We provide a Docker environment for this package. This will automatically start a local Memcached server and run the package tests.

```bash
docker-compose -f docker/docker-compose.yaml run test
```
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
//
//===----------------------------------------------------------------------===//

import Foundation
#if os(Linux)
import Glibc
#else
import Darwin
#endif
import NIOCore

extension ByteBuffer {
Expand Down Expand Up @@ -44,15 +48,15 @@ extension ByteBuffer {
}

extension ByteBuffer {
/// Serialize and writes MemcachedFlags to the ByteBuffer.
/// Serialize and writes MemcacheFlags to the ByteBuffer.
///
/// This method runs a loop over the flags contained in a MemcachedFlags instance.
/// This method runs a loop over the flags contained in a MemcacheFlags instance.
/// For each flag that is set to true, its corresponding byte value,
/// followed by a whitespace character, is added to the ByteBuffer.
///
/// - parameters:
/// - flags: An instance of MemcachedFlags that holds the flags intended to be serialized and written to the ByteBuffer.
mutating func writeMemcachedFlags(flags: MemcachedFlags) {
/// - flags: An instance of MemcacheFlags that holds the flags intended to be serialized and written to the ByteBuffer.
mutating func writeMemcacheFlags(flags: MemcacheFlags) {
// Ensure that both storageMode and arithmeticMode aren't set at the same time.
precondition(!(flags.storageMode != nil && flags.arithmeticMode != nil), "Cannot specify both a storage and arithmetic mode.")

Expand Down Expand Up @@ -127,9 +131,9 @@ extension ByteBuffer {
extension ByteBuffer {
/// Parses flags from this `ByteBuffer`, advancing the reader index accordingly.
///
/// - returns: A `MemcachedFlags` instance populated with the flags read from the buffer.
mutating func readMemcachedFlags() -> MemcachedFlags {
let flags = MemcachedFlags()
/// - returns: A `MemcacheFlags` instance populated with the flags read from the buffer.
mutating func readMemcacheFlags() -> MemcacheFlags {
let flags = MemcacheFlags()
while let nextByte = self.getInteger(at: self.readerIndex, as: UInt8.self) {
switch nextByte {
case UInt8.whitespace:
Expand Down
Loading