@@ -24,7 +24,7 @@ export class FlatFile extends StorageAPI.Async {
2424 private dir : string ;
2525 private logging ?: boolean ;
2626 private ttl ?: boolean ;
27- private requests : Promise < any > ;
27+ private fileQueues : { [ key : string ] : Promise < any > } ;
2828
2929 constructor ( {
3030 dir,
@@ -40,14 +40,32 @@ export class FlatFile extends StorageAPI.Async {
4040 this . dir = dir ;
4141 this . logging = logging || false ;
4242 this . ttl = ttl || false ;
43- this . requests = Promise . resolve ( ) ;
43+ this . fileQueues = { } ;
4444 }
4545
46- private async request < T extends any = any > (
47- action : ( ) => Promise < T >
48- ) : Promise < T > {
49- this . requests = this . requests . then ( action , action ) ;
50- return this . requests ;
46+ private async chainRequest (
47+ key : string ,
48+ request : ( ) => Promise < any >
49+ ) : Promise < any > {
50+ if ( ! ( key in this . fileQueues ) ) this . fileQueues [ key ] = Promise . resolve ( ) ;
51+
52+ this . fileQueues [ key ] = this . fileQueues [ key ] . then ( request , request ) ;
53+ return this . fileQueues [ key ] ;
54+ }
55+
56+ private async getItem < T extends any = any > ( key : string ) : Promise < T > {
57+ return this . chainRequest ( key , ( ) => this . games . getItem ( key ) ) ;
58+ }
59+
60+ private async setItem < T extends any = any > (
61+ key : string ,
62+ value : T
63+ ) : Promise < any > {
64+ return this . chainRequest ( key , ( ) => this . games . setItem ( key , value ) ) ;
65+ }
66+
67+ private async removeItem ( key : string ) : Promise < void > {
68+ return this . chainRequest ( key , ( ) => this . games . removeItem ( key ) ) ;
5169 }
5270
5371 async connect ( ) {
@@ -66,8 +84,7 @@ export class FlatFile extends StorageAPI.Async {
6684 // Store initial state separately for easy retrieval later.
6785 const key = InitialStateKey ( gameID ) ;
6886
69- await this . request ( ( ) => this . games . setItem ( key , opts . initialState ) ) ;
70-
87+ await this . setItem ( key , opts . initialState ) ;
7188 await this . setState ( gameID , opts . initialState ) ;
7289 await this . setMetadata ( gameID , opts . metadata ) ;
7390 }
@@ -79,30 +96,22 @@ export class FlatFile extends StorageAPI.Async {
7996 let result = { } as StorageAPI . FetchFields ;
8097
8198 if ( opts . state ) {
82- result . state = ( await this . request ( ( ) =>
83- this . games . getItem ( gameID )
84- ) ) as State ;
99+ result . state = ( await this . getItem ( gameID ) ) as State ;
85100 }
86101
87102 if ( opts . metadata ) {
88103 const key = MetadataKey ( gameID ) ;
89- result . metadata = ( await this . request ( ( ) =>
90- this . games . getItem ( key )
91- ) ) as Server . GameMetadata ;
104+ result . metadata = ( await this . getItem ( key ) ) as Server . GameMetadata ;
92105 }
93106
94107 if ( opts . log ) {
95108 const key = LogKey ( gameID ) ;
96- result . log = ( await this . request ( ( ) =>
97- this . games . getItem ( key )
98- ) ) as LogEntry [ ] ;
109+ result . log = ( await this . getItem ( key ) ) as LogEntry [ ] ;
99110 }
100111
101112 if ( opts . initialState ) {
102113 const key = InitialStateKey ( gameID ) ;
103- result . initialState = ( await this . request ( ( ) =>
104- this . games . getItem ( key )
105- ) ) as State ;
114+ result . initialState = ( await this . getItem ( key ) ) as State ;
106115 }
107116
108117 return result as StorageAPI . FetchResult < O > ;
@@ -115,33 +124,32 @@ export class FlatFile extends StorageAPI.Async {
115124 async setState ( id : string , state : State , deltalog ?: LogEntry [ ] ) {
116125 if ( deltalog && deltalog . length > 0 ) {
117126 const key = LogKey ( id ) ;
118- const log : LogEntry [ ] =
119- ( ( await this . request ( ( ) => this . games . getItem ( key ) ) ) as LogEntry [ ] ) ||
120- [ ] ;
127+ const log : LogEntry [ ] = ( ( await this . getItem ( key ) ) as LogEntry [ ] ) || [ ] ;
121128
122- await this . request ( ( ) => this . games . setItem ( key , log . concat ( deltalog ) ) ) ;
129+ await this . setItem ( key , log . concat ( deltalog ) ) ;
123130 }
124131
125- return await this . request ( ( ) => this . games . setItem ( id , state ) ) ;
132+ return await this . setItem ( id , state ) ;
126133 }
127134
128135 async setMetadata ( id : string , metadata : Server . GameMetadata ) : Promise < void > {
129136 const key = MetadataKey ( id ) ;
130137
131- return await this . request ( ( ) => this . games . setItem ( key , metadata ) ) ;
138+ return await this . setItem ( key , metadata ) ;
132139 }
133140
134141 async wipe ( id : string ) {
135142 var keys = await this . games . keys ( ) ;
136143 if ( ! ( keys . indexOf ( id ) > - 1 ) ) return ;
137144
138- await this . request ( ( ) => this . games . removeItem ( id ) ) ;
139- await this . request ( ( ) => this . games . removeItem ( LogKey ( id ) ) ) ;
140- await this . request ( ( ) => this . games . removeItem ( MetadataKey ( id ) ) ) ;
145+ await this . removeItem ( id ) ;
146+ await this . removeItem ( InitialStateKey ( id ) ) ;
147+ await this . removeItem ( LogKey ( id ) ) ;
148+ await this . removeItem ( MetadataKey ( id ) ) ;
141149 }
142150
143151 async listGames ( ) : Promise < string [ ] > {
144- const keys = await this . request ( ( ) => this . games . keys ( ) ) ;
152+ const keys = await this . games . keys ( ) ;
145153 const suffix = ':metadata' ;
146154 return keys
147155 . filter ( k => k . endsWith ( suffix ) )
0 commit comments