Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: Source/modules/cachestorage/Cache.cpp

Issue 1124403005: CacheStorage: Implement Cache.addAll() behind a flag (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix test failure Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/modules/cachestorage/Cache.h ('k') | Source/modules/cachestorage/Cache.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "modules/cachestorage/Cache.h" 6 #include "modules/cachestorage/Cache.h"
7 7
8 #include "bindings/core/v8/CallbackPromiseAdapter.h" 8 #include "bindings/core/v8/CallbackPromiseAdapter.h"
9 #include "bindings/core/v8/ExceptionState.h" 9 #include "bindings/core/v8/ExceptionState.h"
10 #include "bindings/core/v8/ScriptPromiseResolver.h" 10 #include "bindings/core/v8/ScriptPromiseResolver.h"
11 #include "bindings/core/v8/ScriptState.h" 11 #include "bindings/core/v8/ScriptState.h"
12 #include "bindings/core/v8/V8Binding.h"
12 #include "bindings/core/v8/V8ThrowException.h" 13 #include "bindings/core/v8/V8ThrowException.h"
13 #include "bindings/modules/v8/V8Response.h" 14 #include "bindings/modules/v8/V8Response.h"
14 #include "core/dom/DOMException.h" 15 #include "core/dom/DOMException.h"
15 #include "modules/cachestorage/CacheStorageError.h" 16 #include "modules/cachestorage/CacheStorageError.h"
16 #include "modules/fetch/BodyStreamBuffer.h" 17 #include "modules/fetch/BodyStreamBuffer.h"
17 #include "modules/fetch/GlobalFetch.h" 18 #include "modules/fetch/GlobalFetch.h"
18 #include "modules/fetch/Request.h" 19 #include "modules/fetch/Request.h"
19 #include "modules/fetch/Response.h" 20 #include "modules/fetch/Response.h"
20 #include "public/platform/WebServiceWorkerCache.h" 21 #include "public/platform/WebServiceWorkerCache.h"
21 22
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 { 129 {
129 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason); 130 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason);
130 m_resolver->reject(CacheStorageError::createException(*reason)); 131 m_resolver->reject(CacheStorageError::createException(*reason));
131 m_resolver.clear(); 132 m_resolver.clear();
132 } 133 }
133 134
134 private: 135 private:
135 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; 136 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
136 }; 137 };
137 138
138 ScriptPromise rejectAsNotImplemented(ScriptState* scriptState) 139 // This class provides Promise.all() for ScriptPromise.
139 { 140 // TODO(nhiroki): Move this somewhere else so that other components can reuse.
140 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError, "Cache is not implemented")); 141 // TODO(nhiroki): Unfortunately, we have to go through V8 to wait for the fetch
141 } 142 // promise. It should be better to achieve this only within C++ world.
143 class CacheStoragePromiseAll final : public GarbageCollectedFinalized<CacheStora gePromiseAll> {
144 public:
145 CacheStoragePromiseAll(Vector<ScriptPromise> promises, PassRefPtrWillBeRawPt r<ScriptPromiseResolver> resolver)
146 : m_numberOfPendingPromises(promises.size())
147 , m_resolver(resolver)
148 {
149 m_values.resize(promises.size());
150 for (size_t i = 0; i < promises.size(); ++i)
151 promises[i].then(createFulfillFunction(i), createRejectFunction());
152 }
153
154 void onFulfilled(size_t index, const ScriptValue& value)
155 {
156 ASSERT(index < m_values.size());
157 if (m_isSettled)
158 return;
159 m_values[index] = value;
160 if (--m_numberOfPendingPromises > 0)
161 return;
162 m_isSettled = true;
163 m_resolver->resolve(m_values);
164 }
165
166 void onRejected(const ScriptValue& value)
167 {
168 if (m_isSettled)
169 return;
170 m_isSettled = true;
171 m_resolver->reject(value);
172 }
173
174 ScriptPromise promise() { return m_resolver->promise(); }
175
176 DEFINE_INLINE_VIRTUAL_TRACE()
177 {
178 visitor->trace(m_resolver);
179 visitor->trace(m_values);
180 }
181
182 private:
183 class AdapterFunction : public ScriptFunction {
184 public:
185 enum ResolveType {
186 Fulfilled,
187 Rejected,
188 };
189
190 static v8::Local<v8::Function> create(ScriptState* scriptState, ResolveT ype resolveType, size_t index, CacheStoragePromiseAll* promiseAll)
191 {
192 AdapterFunction* self = new AdapterFunction(scriptState, resolveType , index, promiseAll);
193 return self->bindToV8Function();
194 }
195
196 DEFINE_INLINE_VIRTUAL_TRACE()
197 {
198 visitor->trace(m_promiseAll);
199 ScriptFunction::trace(visitor);
200 }
201
202 private:
203 AdapterFunction(ScriptState* scriptState, ResolveType resolveType, size_ t index, CacheStoragePromiseAll* promiseAll)
204 : ScriptFunction(scriptState)
205 , m_resolveType(resolveType)
206 , m_index(index)
207 , m_promiseAll(promiseAll) { }
208
209 ScriptValue call(ScriptValue value) override
210 {
211 if (m_resolveType == Fulfilled)
212 m_promiseAll->onFulfilled(m_index, value);
213 else
214 m_promiseAll->onRejected(value);
215 return ScriptValue(scriptState(), m_promiseAll->promise().v8Value()) ;
216 }
217
218 const ResolveType m_resolveType;
219 const size_t m_index;
220 Member<CacheStoragePromiseAll> m_promiseAll;
221 };
222
223 v8::Local<v8::Function> createFulfillFunction(size_t index)
224 {
225 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Fulfilled, index, this);
226 }
227
228 v8::Local<v8::Function> createRejectFunction()
229 {
230 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Rejected, 0, this);
231 }
232
233 size_t m_numberOfPendingPromises;
234 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
235 bool m_isSettled = false;
236 Vector<ScriptValue> m_values;
237 };
142 238
143 } // namespace 239 } // namespace
144 240
145 class Cache::FetchResolvedForAdd final : public ScriptFunction { 241 class Cache::FetchResolvedForAdd final : public ScriptFunction {
146 public: 242 public:
147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , Request* request) 243 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , const HeapVector<Member<Request>>& requests)
148 { 244 {
149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request); 245 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, requests);
150 return self->bindToV8Function(); 246 return self->bindToV8Function();
151 } 247 }
152 248
153 ScriptValue call(ScriptValue value) override 249 ScriptValue call(ScriptValue value) override
154 { 250 {
155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol ate(), value.v8Value()); 251 NonThrowableExceptionState exceptionState;
156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Me mber<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); 252 HeapVector<Member<Response>> responses = toMemberNativeArray<Response, V 8Response>(value.v8Value(), m_requests.size(), scriptState()->isolate(), excepti onState);
253 ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_requests, r esponses);
157 return ScriptValue(scriptState(), putPromise.v8Value()); 254 return ScriptValue(scriptState(), putPromise.v8Value());
158 } 255 }
159 256
160 DEFINE_INLINE_VIRTUAL_TRACE() 257 DEFINE_INLINE_VIRTUAL_TRACE()
161 { 258 {
162 visitor->trace(m_cache); 259 visitor->trace(m_cache);
163 visitor->trace(m_request); 260 visitor->trace(m_requests);
164 ScriptFunction::trace(visitor); 261 ScriptFunction::trace(visitor);
165 } 262 }
166 263
167 private: 264 private:
168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request ) 265 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, const HeapVector <Member<Request>>& requests)
169 : ScriptFunction(scriptState) 266 : ScriptFunction(scriptState)
170 , m_cache(cache) 267 , m_cache(cache)
171 , m_request(request) 268 , m_requests(requests)
172 { 269 {
173 } 270 }
174 271
175 Member<Cache> m_cache; 272 Member<Cache> m_cache;
176 Member<Request> m_request; 273 HeapVector<Member<Request>> m_requests;
177 }; 274 };
178 275
179 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> { 276 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> {
180 public: 277 public:
181 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver) 278 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver)
182 : m_numberOfRemainingOperations(numberOfOperations) 279 : m_numberOfRemainingOperations(numberOfOperations)
183 , m_cache(cache) 280 , m_cache(cache)
184 , m_resolver(resolver) 281 , m_resolver(resolver)
185 { 282 {
186 ASSERT(0 < m_numberOfRemainingOperations); 283 ASSERT(0 < m_numberOfRemainingOperations);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 return matchAllImpl(scriptState, request.getAsRequest(), options); 388 return matchAllImpl(scriptState, request.getAsRequest(), options);
292 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); 389 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState);
293 if (exceptionState.hadException()) 390 if (exceptionState.hadException())
294 return ScriptPromise(); 391 return ScriptPromise();
295 return matchAllImpl(scriptState, newRequest, options); 392 return matchAllImpl(scriptState, newRequest, options);
296 } 393 }
297 394
298 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState) 395 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState)
299 { 396 {
300 ASSERT(!request.isNull()); 397 ASSERT(!request.isNull());
301 Request* newRequest; 398 HeapVector<Member<Request>> requests;
302 if (request.isRequest()) { 399 if (request.isRequest()) {
303 newRequest = request.getAsRequest(); 400 requests.append(request.getAsRequest());
304 } else { 401 } else {
305 newRequest = Request::create(scriptState, request.getAsUSVString(), exce ptionState); 402 requests.append(Request::create(scriptState, request.getAsUSVString(), e xceptionState));
306
307 if (exceptionState.hadException()) 403 if (exceptionState.hadException())
308 return ScriptPromise(); 404 return ScriptPromise();
309 } 405 }
310 406
311 Vector<Request*> requestVector; 407 return addAllImpl(scriptState, requests, exceptionState);
312 requestVector.append(newRequest);
313 return addAllImpl(scriptState, requestVector, exceptionState);
314 } 408 }
315 409
316 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests) 410 ScriptPromise Cache::addAll(ScriptState* scriptState, const HeapVector<RequestIn fo>& rawRequests, ExceptionState& exceptionState)
317 { 411 {
318 // FIXME: Implement this. 412 HeapVector<Member<Request>> requests;
319 return rejectAsNotImplemented(scriptState); 413 for (RequestInfo request : rawRequests) {
414 if (request.isRequest()) {
415 requests.append(request.getAsRequest());
416 } else {
417 requests.append(Request::create(scriptState, request.getAsUSVString( ), exceptionState));
418 if (exceptionState.hadException())
419 return ScriptPromise();
420 }
421 }
422
423 return addAllImpl(scriptState, requests, exceptionState);
320 } 424 }
321 425
322 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) 426 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
323 { 427 {
324 ASSERT(!request.isNull()); 428 ASSERT(!request.isNull());
325 if (request.isRequest()) 429 if (request.isRequest())
326 return deleteImpl(scriptState, request.getAsRequest(), options); 430 return deleteImpl(scriptState, request.getAsRequest(), options);
327 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); 431 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState);
328 if (exceptionState.hadException()) 432 if (exceptionState.hadException())
329 return ScriptPromise(); 433 return ScriptPromise();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 { 491 {
388 WebServiceWorkerRequest webRequest; 492 WebServiceWorkerRequest webRequest;
389 request->populateWebServiceWorkerRequest(webRequest); 493 request->populateWebServiceWorkerRequest(webRequest);
390 494
391 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); 495 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
392 const ScriptPromise promise = resolver->promise(); 496 const ScriptPromise promise = resolver->promise();
393 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options)); 497 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options));
394 return promise; 498 return promise;
395 } 499 }
396 500
397 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<Request*> & requests, ExceptionState& exceptionState) 501 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const HeapVector<Membe r<Request>>& requests, ExceptionState& exceptionState)
398 { 502 {
399 // TODO(gavinp,nhiroki): Implement addAll for more than one element.
400 ASSERT(requests.size() == 1);
401
402 Vector<RequestInfo> requestInfos; 503 Vector<RequestInfo> requestInfos;
403 requestInfos.resize(requests.size()); 504 requestInfos.resize(requests.size());
505 Vector<ScriptPromise> promises;
506 promises.resize(requests.size());
404 for (size_t i = 0; i < requests.size(); ++i) { 507 for (size_t i = 0; i < requests.size(); ++i) {
405 if (!requests[i]->url().protocolIsInHTTPFamily()) 508 if (!requests[i]->url().protocolIsInHTTPFamily())
406 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\"")); 509 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\""));
407 if (requests[i]->method() != "GET") 510 if (requests[i]->method() != "GET")
408 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method .")); 511 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method ."));
409 requestInfos[i].setRequest(requests[i]); 512 requestInfos[i].setRequest(requests[i]);
513
514 promises[i] = m_scopedFetcher->fetch(scriptState, requestInfos[i], Dicti onary(), exceptionState);
410 } 515 }
411 516
412 ScriptPromise fetchPromise = m_scopedFetcher->fetch(scriptState, requestInfo s[0], Dictionary(), exceptionState); 517 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
413 return fetchPromise.then(FetchResolvedForAdd::create(scriptState, this, requ ests[0])); 518 CacheStoragePromiseAll* promiseAll = new CacheStoragePromiseAll(promises, re solver.get());
519 return promiseAll->promise().then(FetchResolvedForAdd::create(scriptState, t his, requests));
414 } 520 }
415 521
416 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options) 522 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options)
417 { 523 {
418 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); 524 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
419 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; 525 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e;
420 request->populateWebServiceWorkerRequest(batchOperations[0].request); 526 request->populateWebServiceWorkerRequest(batchOperations[0].request);
421 batchOperations[0].matchParams = toWebQueryParams(options); 527 batchOperations[0].matchParams = toWebQueryParams(options);
422 528
423 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); 529 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); 599 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options));
494 return promise; 600 return promise;
495 } 601 }
496 602
497 WebServiceWorkerCache* Cache::webCache() const 603 WebServiceWorkerCache* Cache::webCache() const
498 { 604 {
499 return m_webCache.get(); 605 return m_webCache.get();
500 } 606 }
501 607
502 } // namespace blink 608 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/cachestorage/Cache.h ('k') | Source/modules/cachestorage/Cache.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698