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: Created 5 years, 6 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
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 {
140 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError, "Cache is not implemented"));
141 }
142
143 } // namespace 139 } // namespace
144 140
145 class Cache::FetchResolvedForAdd final : public ScriptFunction { 141 class Cache::FetchResolvedForAdd final : public ScriptFunction {
146 public: 142 public:
147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , Request* request) 143 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , const HeapVector<Member<Request>>& requests)
148 { 144 {
149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request); 145 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, requests);
150 return self->bindToV8Function(); 146 return self->bindToV8Function();
151 } 147 }
152 148
153 ScriptValue call(ScriptValue value) override 149 ScriptValue call(ScriptValue value) override
154 { 150 {
155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol ate(), value.v8Value()); 151 NonThrowableExceptionState exceptionState;
156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Me mber<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); 152 HeapVector<Member<Response>> responses = toMemberNativeArray<Response, V 8Response>(value.v8Value(), m_requests.size(), scriptState()->isolate(), excepti onState);
153 ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_requests, r esponses);
157 return ScriptValue(scriptState(), putPromise.v8Value()); 154 return ScriptValue(scriptState(), putPromise.v8Value());
158 } 155 }
159 156
160 DEFINE_INLINE_VIRTUAL_TRACE() 157 DEFINE_INLINE_VIRTUAL_TRACE()
161 { 158 {
162 visitor->trace(m_cache); 159 visitor->trace(m_cache);
163 visitor->trace(m_request); 160 visitor->trace(m_requests);
164 ScriptFunction::trace(visitor); 161 ScriptFunction::trace(visitor);
165 } 162 }
166 163
167 private: 164 private:
168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request ) 165 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, const HeapVector <Member<Request>>& requests)
169 : ScriptFunction(scriptState) 166 : ScriptFunction(scriptState)
170 , m_cache(cache) 167 , m_cache(cache)
171 , m_request(request) 168 , m_requests(requests)
172 { 169 {
173 } 170 }
174 171
175 Member<Cache> m_cache; 172 Member<Cache> m_cache;
176 Member<Request> m_request; 173 HeapVector<Member<Request>> m_requests;
177 }; 174 };
178 175
179 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> { 176 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> {
180 public: 177 public:
181 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver) 178 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver)
182 : m_numberOfRemainingOperations(numberOfOperations) 179 : m_numberOfRemainingOperations(numberOfOperations)
183 , m_cache(cache) 180 , m_cache(cache)
184 , m_resolver(resolver) 181 , m_resolver(resolver)
185 { 182 {
186 ASSERT(0 < m_numberOfRemainingOperations); 183 ASSERT(0 < m_numberOfRemainingOperations);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 return matchAllImpl(scriptState, request.getAsRequest(), options); 282 return matchAllImpl(scriptState, request.getAsRequest(), options);
286 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); 283 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState);
287 if (exceptionState.hadException()) 284 if (exceptionState.hadException())
288 return ScriptPromise(); 285 return ScriptPromise();
289 return matchAllImpl(scriptState, newRequest, options); 286 return matchAllImpl(scriptState, newRequest, options);
290 } 287 }
291 288
292 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState) 289 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState)
293 { 290 {
294 ASSERT(!request.isNull()); 291 ASSERT(!request.isNull());
295 Request* newRequest; 292 HeapVector<Member<Request>> requests;
296 if (request.isRequest()) { 293 if (request.isRequest()) {
297 newRequest = request.getAsRequest(); 294 requests.append(request.getAsRequest());
298 } else { 295 } else {
299 newRequest = Request::create(scriptState, request.getAsUSVString(), exce ptionState); 296 requests.append(Request::create(scriptState, request.getAsUSVString(), e xceptionState));
300
301 if (exceptionState.hadException()) 297 if (exceptionState.hadException())
302 return ScriptPromise(); 298 return ScriptPromise();
303 } 299 }
304 300
305 Vector<Request*> requestVector; 301 return addAllImpl(scriptState, requests, exceptionState);
306 requestVector.append(newRequest);
307 return addAllImpl(scriptState, requestVector, exceptionState);
308 } 302 }
309 303
310 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests) 304 ScriptPromise Cache::addAll(ScriptState* scriptState, const HeapVector<RequestIn fo>& rawRequests, ExceptionState& exceptionState)
311 { 305 {
312 // FIXME: Implement this. 306 HeapVector<Member<Request>> requests;
313 return rejectAsNotImplemented(scriptState); 307 for (RequestInfo request : rawRequests) {
308 if (request.isRequest()) {
309 requests.append(request.getAsRequest());
310 } else {
311 requests.append(Request::create(scriptState, request.getAsUSVString( ), exceptionState));
312 if (exceptionState.hadException())
313 return ScriptPromise();
314 }
315 }
316
317 return addAllImpl(scriptState, requests, exceptionState);
314 } 318 }
315 319
316 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) 320 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
317 { 321 {
318 ASSERT(!request.isNull()); 322 ASSERT(!request.isNull());
319 if (request.isRequest()) 323 if (request.isRequest())
320 return deleteImpl(scriptState, request.getAsRequest(), options); 324 return deleteImpl(scriptState, request.getAsRequest(), options);
321 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); 325 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState);
322 if (exceptionState.hadException()) 326 if (exceptionState.hadException())
323 return ScriptPromise(); 327 return ScriptPromise();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 { 385 {
382 WebServiceWorkerRequest webRequest; 386 WebServiceWorkerRequest webRequest;
383 request->populateWebServiceWorkerRequest(webRequest); 387 request->populateWebServiceWorkerRequest(webRequest);
384 388
385 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); 389 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
386 const ScriptPromise promise = resolver->promise(); 390 const ScriptPromise promise = resolver->promise();
387 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options)); 391 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options));
388 return promise; 392 return promise;
389 } 393 }
390 394
391 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<Request*> & requests, ExceptionState& exceptionState) 395 // This class provides Promise.all() for ScriptPromise.
396 class ScriptPromiseAll final : public GarbageCollectedFinalized<ScriptPromiseAll > {
jkarlin 2015/06/26 19:40:28 I'm sad that we have to go through V8 to wait on t
nhiroki 2015/07/02 09:31:54 Done.
397 public:
398 class AdapterFunction : public ScriptFunction {
399 public:
400 enum ResolveType {
401 Fulfilled,
402 Rejected,
403 };
404
405 static v8::Local<v8::Function> create(ScriptState* scriptState, ResolveT ype resolveType, size_t index, ScriptPromiseAll* promiseAll)
406 {
407 AdapterFunction* self = new AdapterFunction(scriptState, resolveType , index, promiseAll);
408 return self->bindToV8Function();
409 }
410
411 DEFINE_INLINE_VIRTUAL_TRACE()
412 {
413 visitor->trace(m_promiseAll);
414 ScriptFunction::trace(visitor);
415 }
416
417 private:
418 AdapterFunction(ScriptState* scriptState, ResolveType resolveType, size_ t index, ScriptPromiseAll* promiseAll)
419 : ScriptFunction(scriptState)
420 , m_resolveType(resolveType)
421 , m_index(index)
422 , m_promiseAll(promiseAll) { }
423
424 ScriptValue call(ScriptValue value) override
425 {
426 if (m_resolveType == Fulfilled) {
427 m_promiseAll->onFulfilled(m_index, value);
428 } else {
429 m_promiseAll->onRejected(value);
430 }
431 return ScriptValue(scriptState(), m_promiseAll->promise().v8Value()) ;
432 }
433
434 const ResolveType m_resolveType;
435 const size_t m_index;
436 Member<ScriptPromiseAll> m_promiseAll;
437 };
438
439 ScriptPromiseAll(Vector<ScriptPromise> promises, PassRefPtrWillBeRawPtr<Scri ptPromiseResolver> resolver)
440 : m_numberOfPendingPromises(promises.size())
441 , m_resolver(resolver)
442 {
443 m_values.resize(promises.size());
444 for (size_t i = 0; i < promises.size(); ++i)
445 promises[i].then(createFulfillFunction(i), createRejectFunction());
446 }
447
448 void onFulfilled(size_t index, const ScriptValue& value)
449 {
450 ASSERT(index < m_values.size());
451 if (m_isResolvedOrRejected)
452 return;
453 m_values[index] = value;
454 if (--m_numberOfPendingPromises > 0)
455 return;
456 m_isResolvedOrRejected = true;
457 m_resolver->resolve(m_values);
458 }
459
460 void onRejected(const ScriptValue& value)
461 {
462 if (m_isResolvedOrRejected)
463 return;
464 m_isResolvedOrRejected = true;
465 m_resolver->reject(value);
466 }
467
468 v8::Local<v8::Function> createFulfillFunction(size_t index)
jkarlin 2015/06/26 19:40:28 The create functions should be private
nhiroki 2015/07/02 09:31:54 Done.
469 {
470 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Fulfilled, index, this);
471 }
472
473 v8::Local<v8::Function> createRejectFunction()
474 {
475 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Rejected, 0, this);
476 }
477
478 ScriptPromise promise() { return m_resolver->promise(); }
479
480 DEFINE_INLINE_VIRTUAL_TRACE()
481 {
482 visitor->trace(m_resolver);
483 visitor->trace(m_values);
484 }
485
486 private:
487 size_t m_numberOfPendingPromises;
488 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
489 bool m_isResolvedOrRejected = false;
jkarlin 2015/06/26 19:40:28 I believe 'settled' is the term for a promise that
nhiroki 2015/07/02 09:31:54 Done.
490 Vector<ScriptValue> m_values;
491 };
492
493 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const HeapVector<Membe r<Request>>& requests, ExceptionState& exceptionState)
392 { 494 {
393 // TODO(gavinp,nhiroki): Implement addAll for more than one element.
394 ASSERT(requests.size() == 1);
395
396 Vector<RequestInfo> requestInfos; 495 Vector<RequestInfo> requestInfos;
397 requestInfos.resize(requests.size()); 496 requestInfos.resize(requests.size());
497 Vector<ScriptPromise> promises;
498 promises.resize(requests.size());
398 for (size_t i = 0; i < requests.size(); ++i) { 499 for (size_t i = 0; i < requests.size(); ++i) {
399 if (!requests[i]->url().protocolIsInHTTPFamily()) 500 if (!requests[i]->url().protocolIsInHTTPFamily())
400 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\"")); 501 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\""));
401 if (requests[i]->method() != "GET") 502 if (requests[i]->method() != "GET")
402 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method .")); 503 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method ."));
403 requestInfos[i].setRequest(requests[i]); 504 requestInfos[i].setRequest(requests[i]);
505
506 promises[i] = m_scopedFetcher->fetch(scriptState, requestInfos[i], Dicti onary(), exceptionState);
404 } 507 }
405 508
406 ScriptPromise fetchPromise = m_scopedFetcher->fetch(scriptState, requestInfo s[0], Dictionary(), exceptionState); 509 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
407 return fetchPromise.then(FetchResolvedForAdd::create(scriptState, this, requ ests[0])); 510 ScriptPromiseAll* promiseAll = new ScriptPromiseAll(promises, resolver.get() );
511 return promiseAll->promise().then(FetchResolvedForAdd::create(scriptState, t his, requests));
408 } 512 }
409 513
410 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options) 514 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options)
411 { 515 {
412 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); 516 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
413 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; 517 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e;
414 request->populateWebServiceWorkerRequest(batchOperations[0].request); 518 request->populateWebServiceWorkerRequest(batchOperations[0].request);
415 batchOperations[0].matchParams = toWebQueryParams(options); 519 batchOperations[0].matchParams = toWebQueryParams(options);
416 520
417 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); 521 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); 583 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options));
480 return promise; 584 return promise;
481 } 585 }
482 586
483 WebServiceWorkerCache* Cache::webCache() const 587 WebServiceWorkerCache* Cache::webCache() const
484 { 588 {
485 return m_webCache.get(); 589 return m_webCache.get();
486 } 590 }
487 591
488 } // namespace blink 592 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698