Skip to content

Commit

Permalink
Merge pull request #723 from openkraken/refactor/http-cache-offline
Browse files Browse the repository at this point in the history
♻️ refactor: offline http cache
  • Loading branch information
answershuto authored Oct 12, 2021
2 parents 8f1b5f5 + 5a09f19 commit eb01ba6
Show file tree
Hide file tree
Showing 12 changed files with 441 additions and 349 deletions.
8 changes: 4 additions & 4 deletions integration_tests/lib/custom/custom_object_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ class CustomObjectElement implements ObjectElementClient {
@override
void dispose() {
objectElementHost.updateChildTextureBox(null);
controller!.pause();
controller!.dispose();
controller?.pause();
controller?.dispose();
controller = null;
}

Expand All @@ -147,8 +147,8 @@ class CustomObjectElement implements ObjectElementClient {

@override
void didDetachRenderer() {
controller!.pause();
controller!.dispose();
controller?.pause();
controller?.dispose();
controller = null;
}

Expand Down
41 changes: 24 additions & 17 deletions kraken/lib/src/dom/elements/a.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,30 @@ class AnchorElement extends Element {
addEvent(EVENT_CLICK);
}

String get pathname {
if (_href != null) {
return Uri.parse(_href!).path;
} else {
return '';
}
}

@override
void handleMouseEvent(String eventType, TapUpDetails details) {
super.handleMouseEvent(eventType, details);

String? href = _href;
if (href == null) return;

Uri uri = Uri.parse(href);
KrakenController rootController = elementManager.controller.view.rootController;
String? sourceUrl = rootController.bundleURL;
String scheme;
if (!uri.hasScheme) {
if (sourceUrl != null) {
Uri sourceUri = Uri.parse(sourceUrl);
scheme = sourceUri.scheme;
} else {
scheme = 'http';
}
} else {
scheme = uri.scheme;
if (href != null) {
String baseUrl = elementManager.controller.href;
Uri baseUri = Uri.parse(baseUrl);
Uri resolvedUri = elementManager.controller.uriParser!.resolve(baseUri, Uri.parse(href));
elementManager.controller.view.handleNavigationAction(
baseUrl, resolvedUri.toString(), _getNavigationType(resolvedUri.scheme));
}
elementManager.controller.view.handleNavigationAction(sourceUrl, href, _getNavigationType(scheme));
}

KrakenNavigationType _getNavigationType(String scheme) {
switch (scheme) {
switch (scheme.toLowerCase()) {
case 'http':
case 'https':
case 'file':
Expand All @@ -60,6 +58,15 @@ class AnchorElement extends Element {
return KrakenNavigationType.navigate;
}

@override
getProperty(String key) {
switch (key) {
case 'pathname':
return pathname;
}
return super.getProperty(key);
}

@override
void setProperty(String key, dynamic value) {
super.setProperty(key, value);
Expand Down
6 changes: 3 additions & 3 deletions kraken/lib/src/dom/elements/object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ class ObjectElement extends Element implements ObjectElementHost {
_objectElementClient = _objectElementClientFactory(this);
}

Future<dynamic> initElementClient() async {
Future initElementClient() async {
try {
await _objectElementClient.initElementClient(properties);
} catch (e) {
print(e);
} catch (error, stackTrace) {
print('$error\n$stackTrace');
}
}

Expand Down
14 changes: 8 additions & 6 deletions kraken/lib/src/foundation/http_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,19 @@ class HttpCacheController {

// Get the CacheObject by uri, no validation needed here.
Future<HttpCacheObject> getCacheObject(Uri uri) async {
HttpCacheObject cacheObject;

// L2 cache in memory.
final String key = _getCacheKey(uri);
if (_caches.containsKey(key)) {
return _caches[key]!;
cacheObject = _caches[key]!;
} else {
// Get cache in disk.
final int hash = key.hashCode;
final Directory cacheDirectory = await getCacheDirectory();
cacheObject = HttpCacheObject(key, cacheDirectory.path, hash: hash, origin: _origin);
}

// Get cache in disk.
final int hash = key.hashCode;
final Directory cacheDirectory = await getCacheDirectory();
HttpCacheObject cacheObject = HttpCacheObject(key, cacheDirectory.path, hash: hash, origin: _origin);

await cacheObject.read();

return cacheObject;
Expand Down
39 changes: 29 additions & 10 deletions kraken/lib/src/foundation/http_cache_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,13 @@ class HttpCacheObject {
bool isDateTimeValid() => expiredTime != null && expiredTime!.isAfter(DateTime.now());

// Validate the cache-control and expires.
Future<bool> hitLocalCache(HttpClientRequest request) async {
if (!valid) {
await read();
}
return isDateTimeValid();
bool hitLocalCache(HttpClientRequest request) {
return valid && isDateTimeValid();
}

/// Read the index file.
Future<void> read() async {
if (_valid) return;
final bool isIndexFileExist = await _file.exists();
if (!isIndexFileExist) {
// Index file not exist, dispose.
Expand Down Expand Up @@ -173,6 +171,12 @@ class HttpCacheObject {
contentLength = byteData.getUint32(index, Endian.little);
index += 4;

// Invalid cache blob size, mark as invalid.
if (await _blob.length != contentLength) {
_valid = false;
return;
}

// Read url.
int urlLength = byteData.getUint32(index, Endian.little);
index += 4;
Expand Down Expand Up @@ -243,10 +247,11 @@ class HttpCacheObject {

// Remove all the cached files.
Future<void> remove() async {
await Future.wait([
_file.delete(),
_blob.remove(),
]);
if (await _file.exists()) {
await _file.delete();
}
await _blob.remove();

_valid = false;
}

Expand Down Expand Up @@ -350,6 +355,15 @@ class HttpCacheObjectBlob extends EventSink<List<int>> {

HttpCacheObjectBlob(this.path) : _file = File(path);

// The length of the file.
Future<int> get length async {
if (await exists()) {
return await _file.length();
} else {
return 0;
}
}

@override
void add(List<int> data) {
_writer ??= _file.openWrite();
Expand All @@ -370,6 +384,8 @@ class HttpCacheObjectBlob extends EventSink<List<int>> {
// Ensure buffer has been written.
await _writer?.flush();
await _writer?.close();

_writer = null;
}

Future<bool> exists() {
Expand All @@ -381,6 +397,9 @@ class HttpCacheObjectBlob extends EventSink<List<int>> {
}

Future<void> remove() async {
await _file.delete();
if (await _file.exists()) {
await _file.delete();
}
close();
}
}
Loading

0 comments on commit eb01ba6

Please sign in to comment.