@@ -136,21 +136,13 @@ public actor MemcachedConnection {
136136 }
137137 }
138138
139- /// Fetch the value for a key from the Memcache server.
140- ///
141- /// - Parameter key: The key to fetch the value for.
142- /// - Returns: A `Value` containing the fetched value, or `nil` if no value was found.
143- public func get< Value: MemcachedValue > ( _ key: String , as valueType: Value . Type = Value . self) async throws -> Value ? {
139+ /// Send a request to the Memcached server and returns a `MemcachedResponse`.
140+ private func sendRequest( _ request: MemcachedRequest ) async throws -> MemcachedResponse {
144141 switch self . state {
145142 case . initial( _, _, _, let requestContinuation) ,
146143 . running( _, _, _, let requestContinuation) :
147144
148- var flags = MemcachedFlags ( )
149- flags. shouldReturnValue = true
150- let command = MemcachedRequest . GetCommand ( key: key, flags: flags)
151- let request = MemcachedRequest . get ( command)
152-
153- let response = try await withCheckedThrowingContinuation { continuation in
145+ return try await withCheckedThrowingContinuation { continuation in
154146 switch requestContinuation. yield ( ( request, continuation) ) {
155147 case . enqueued:
156148 break
@@ -159,7 +151,31 @@ public actor MemcachedConnection {
159151 default :
160152 break
161153 }
162- } . value
154+ }
155+
156+ case . finished:
157+ throw MemcachedConnectionError . connectionShutdown
158+ }
159+ }
160+
161+ // MARK: - Fetching Values
162+
163+ /// Fetch the value for a key from the Memcache server.
164+ ///
165+ /// - Parameter key: The key to fetch the value for.
166+ /// - Returns: A `Value` containing the fetched value, or `nil` if no value was found.
167+ public func get< Value: MemcachedValue > ( _ key: String , as valueType: Value . Type = Value . self) async throws -> Value ? {
168+ switch self . state {
169+ case . initial( _, _, _, _) ,
170+ . running:
171+
172+ var flags = MemcachedFlags ( )
173+ flags. shouldReturnValue = true
174+
175+ let command = MemcachedRequest . GetCommand ( key: key, flags: flags)
176+ let request = MemcachedRequest . get ( command)
177+
178+ let response = try await sendRequest ( request) . value
163179
164180 if var unwrappedResponse = response {
165181 return Value . readFromBuffer ( & unwrappedResponse)
@@ -171,31 +187,61 @@ public actor MemcachedConnection {
171187 }
172188 }
173189
174- /// Set the value for a key on the Memcache server.
190+ // MARK: - Touch
191+
192+ /// Update the time-to-live for a key.
193+ ///
194+ /// This method changes the expiration time of an existing item without fetching it. If the key does not exist or if the new expiration time is already passed, the operation will not succeed.
175195 ///
176196 /// - Parameters:
177- /// - key: The key to set the value for.
178- /// - value: The `Value` to set for the key.
179- public func set( _ key: String , value: some MemcachedValue ) async throws {
197+ /// - key: The key to update the time-to-live for.
198+ /// - newTimeToLive: The new time-to-live.
199+ /// - Throws: A `MemcachedConnectionError` if the connection is shutdown or if there's an unexpected nil response.
200+ public func touch( _ key: String , newTimeToLive: TimeToLive ) async throws {
180201 switch self . state {
181- case . initial( _, let bufferAllocator, _, let requestContinuation) ,
182- . running( let bufferAllocator, _, _, let requestContinuation) :
202+ case . initial( _, _, _, _) ,
203+ . running:
204+
205+ var flags = MemcachedFlags ( )
206+ flags. timeToLive = newTimeToLive
207+
208+ let command = MemcachedRequest . GetCommand ( key: key, flags: flags)
209+ let request = MemcachedRequest . get ( command)
210+
211+ _ = try await self . sendRequest ( request)
212+
213+ case . finished:
214+ throw MemcachedConnectionError . connectionShutdown
215+ }
216+ }
217+
218+ // MARK: - Setting a Value
219+
220+ /// Sets a value for a specified key in the Memcache server with an optional Time-to-Live (TTL) parameter.
221+ ///
222+ /// - Parameters:
223+ /// - key: The key for which the value is to be set.
224+ /// - value: The `MemcachedValue` to set for the key.
225+ /// - expiration: An optional `TimeToLive` value specifying the TTL (Time-To-Live) for the key-value pair.
226+ /// If provided, the key-value pair will be removed from the cache after the specified TTL duration has passed.
227+ /// If not provided, the key-value pair will persist indefinitely in the cache.
228+ /// - Throws: A `MemcachedConnectionError` if the connection to the Memcached server is shut down.
229+ public func set( _ key: String , value: some MemcachedValue , timeToLive: TimeToLive = . indefinitely) async throws {
230+ switch self . state {
231+ case . initial( _, let bufferAllocator, _, _) ,
232+ . running( let bufferAllocator, _, _, _) :
183233
184234 var buffer = bufferAllocator. buffer ( capacity: 0 )
185235 value. writeToBuffer ( & buffer)
186- let command = MemcachedRequest . SetCommand ( key: key, value: buffer)
236+ var flags : MemcachedFlags ?
237+
238+ flags = MemcachedFlags ( )
239+ flags? . timeToLive = timeToLive
240+
241+ let command = MemcachedRequest . SetCommand ( key: key, value: buffer, flags: flags)
187242 let request = MemcachedRequest . set ( command)
188243
189- _ = try await withCheckedThrowingContinuation { continuation in
190- switch requestContinuation. yield ( ( request, continuation) ) {
191- case . enqueued:
192- break
193- case . dropped, . terminated:
194- continuation. resume ( throwing: MemcachedConnectionError . connectionShutdown)
195- default :
196- break
197- }
198- } . value
244+ _ = try await self . sendRequest ( request)
199245
200246 case . finished:
201247 throw MemcachedConnectionError . connectionShutdown
0 commit comments