11use std:: collections:: hash_map:: HashMap ;
2- use std:: path:: Path ;
3- use std:: sync:: Arc ;
42
5- use crate :: { Options , Result , Status , StatusCode , WriteBatch , DB } ;
3+ use crate :: {
4+ send_response, send_response_result, AsyncDB , Message , Result , Status , StatusCode , WriteBatch ,
5+ DB ,
6+ } ;
67
7- use tokio:: sync:: mpsc;
8- use tokio:: sync:: oneshot;
9- use tokio:: task:: { spawn_blocking, JoinHandle } ;
10-
11- const CHANNEL_BUFFER_SIZE : usize = 32 ;
8+ pub ( crate ) const CHANNEL_BUFFER_SIZE : usize = 32 ;
129
1310#[ derive( Clone , Copy ) ]
1411pub struct SnapshotRef ( usize ) ;
1512
1613/// A request sent to the database thread.
17- enum Request {
14+ pub ( crate ) enum Request {
1815 Close ,
1916 Put { key : Vec < u8 > , val : Vec < u8 > } ,
2017 Delete { key : Vec < u8 > } ,
@@ -28,42 +25,14 @@ enum Request {
2825}
2926
3027/// A response received from the database thread.
31- enum Response {
28+ pub ( crate ) enum Response {
3229 OK ,
3330 Error ( Status ) ,
3431 Value ( Option < Vec < u8 > > ) ,
3532 Snapshot ( SnapshotRef ) ,
3633}
3734
38- /// Contains both a request and a back-channel for the reply.
39- struct Message {
40- req : Request ,
41- resp_channel : oneshot:: Sender < Response > ,
42- }
43-
44- /// `AsyncDB` makes it easy to use LevelDB in a tokio runtime.
45- /// The methods follow very closely the main API (see `DB` type). Iteration is not yet implemented.
46- ///
47- /// TODO: Make it work in other runtimes as well. This is a matter of adapting the blocking thread
48- /// mechanism as well as the channel types.
49- #[ derive( Clone ) ]
50- pub struct AsyncDB {
51- jh : Arc < JoinHandle < ( ) > > ,
52- send : mpsc:: Sender < Message > ,
53- }
54-
5535impl AsyncDB {
56- /// Create a new or open an existing database.
57- pub fn new < P : AsRef < Path > > ( name : P , opts : Options ) -> Result < AsyncDB > {
58- let db = DB :: open ( name, opts) ?;
59- let ( send, recv) = mpsc:: channel ( CHANNEL_BUFFER_SIZE ) ;
60- let jh = spawn_blocking ( move || AsyncDB :: run_server ( db, recv) ) ;
61- Ok ( AsyncDB {
62- jh : Arc :: new ( jh) ,
63- send,
64- } )
65- }
66-
6736 pub async fn close ( & self ) -> Result < ( ) > {
6837 let r = self . process_request ( Request :: Close ) . await ?;
6938 match r {
@@ -182,104 +151,79 @@ impl AsyncDB {
182151 }
183152 }
184153
185- async fn process_request ( & self , req : Request ) -> Result < Response > {
186- let ( tx, rx) = oneshot:: channel ( ) ;
187- let m = Message {
188- req,
189- resp_channel : tx,
190- } ;
191- if let Err ( e) = self . send . send ( m) . await {
192- return Err ( Status {
193- code : StatusCode :: AsyncError ,
194- err : e. to_string ( ) ,
195- } ) ;
196- }
197- let resp = rx. await ;
198- match resp {
199- Err ( e) => Err ( Status {
200- code : StatusCode :: AsyncError ,
201- err : e. to_string ( ) ,
202- } ) ,
203- Ok ( r) => Ok ( r) ,
204- }
205- }
206-
207- fn run_server ( mut db : DB , mut recv : mpsc:: Receiver < Message > ) {
154+ pub ( crate ) fn run_server ( mut db : DB , mut recv : impl ReceiverExt < Message > ) {
208155 let mut snapshots = HashMap :: new ( ) ;
209156 let mut snapshot_counter: usize = 0 ;
210157
211158 while let Some ( message) = recv. blocking_recv ( ) {
212159 match message. req {
213160 Request :: Close => {
214- message. resp_channel . send ( Response :: OK ) . ok ( ) ;
161+ send_response ( message. resp_channel , Response :: OK ) ;
215162 recv. close ( ) ;
216163 return ;
217164 }
218165 Request :: Put { key, val } => {
219166 let ok = db. put ( & key, & val) ;
220- send_response ( message. resp_channel , ok) ;
167+ send_response_result ( message. resp_channel , ok) ;
221168 }
222169 Request :: Delete { key } => {
223170 let ok = db. delete ( & key) ;
224- send_response ( message. resp_channel , ok) ;
171+ send_response_result ( message. resp_channel , ok) ;
225172 }
226173 Request :: Write { batch, sync } => {
227174 let ok = db. write ( batch, sync) ;
228- send_response ( message. resp_channel , ok) ;
175+ send_response_result ( message. resp_channel , ok) ;
229176 }
230177 Request :: Flush => {
231178 let ok = db. flush ( ) ;
232- send_response ( message. resp_channel , ok) ;
179+ send_response_result ( message. resp_channel , ok) ;
233180 }
234181 Request :: GetAt { snapshot, key } => {
235182 let snapshot_id = snapshot. 0 ;
236183 if let Some ( snapshot) = snapshots. get ( & snapshot_id) {
237184 let ok = db. get_at ( snapshot, & key) ;
238185 match ok {
239186 Err ( e) => {
240- message. resp_channel . send ( Response :: Error ( e) ) . ok ( ) ;
187+ send_response ( message. resp_channel , Response :: Error ( e) ) ;
241188 }
242189 Ok ( v) => {
243- message. resp_channel . send ( Response :: Value ( v) ) . ok ( ) ;
190+ send_response ( message. resp_channel , Response :: Value ( v) ) ;
244191 }
245192 } ;
246193 } else {
247- message
248- . resp_channel
249- . send ( Response :: Error ( Status {
194+ send_response (
195+ message . resp_channel ,
196+ Response :: Error ( Status {
250197 code : StatusCode :: AsyncError ,
251198 err : "Unknown snapshot reference: this is a bug" . to_string ( ) ,
252- } ) )
253- . ok ( ) ;
199+ } ) ,
200+ ) ;
254201 }
255202 }
256203 Request :: Get { key } => {
257204 let r = db. get ( & key) ;
258- message. resp_channel . send ( Response :: Value ( r) ) . ok ( ) ;
205+ send_response ( message. resp_channel , Response :: Value ( r) ) ;
259206 }
260207 Request :: GetSnapshot => {
261208 snapshots. insert ( snapshot_counter, db. get_snapshot ( ) ) ;
262209 let sref = SnapshotRef ( snapshot_counter) ;
263210 snapshot_counter += 1 ;
264- message. resp_channel . send ( Response :: Snapshot ( sref) ) . ok ( ) ;
211+ send_response ( message. resp_channel , Response :: Snapshot ( sref) ) ;
265212 }
266213 Request :: DropSnapshot { snapshot } => {
267214 snapshots. remove ( & snapshot. 0 ) ;
268- send_response ( message. resp_channel , Ok ( ( ) ) ) ;
215+ send_response_result ( message. resp_channel , Ok ( ( ) ) ) ;
269216 }
270217 Request :: CompactRange { from, to } => {
271218 let ok = db. compact_range ( & from, & to) ;
272- send_response ( message. resp_channel , ok) ;
219+ send_response_result ( message. resp_channel , ok) ;
273220 }
274221 }
275222 }
276223 }
277224}
278225
279- fn send_response ( ch : oneshot:: Sender < Response > , result : Result < ( ) > ) {
280- if let Err ( e) = result {
281- ch. send ( Response :: Error ( e) ) . ok ( ) ;
282- } else {
283- ch. send ( Response :: OK ) . ok ( ) ;
284- }
226+ pub ( crate ) trait ReceiverExt < T > {
227+ fn blocking_recv ( & mut self ) -> Option < T > ;
228+ fn close ( & mut self ) ;
285229}
0 commit comments