Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow setting code cache directory #33286

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/api/session.md
Expand Up @@ -868,6 +868,20 @@ this session just before normal `preload` scripts run.
Returns `string[]` an array of paths to preload scripts that have been
registered.

#### `ses.setCodeCachePath(path)`

* `path` String - Absolute path to store the v8 generated JS code cache from the renderer.

Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the
respective user data folder.

#### `ses.clearCodeCaches(options)`

* `options` Object
* `urls` String[] (optional) - An array of url corresponding to the resource whose generated code cache needs to be removed. If the list is empty then all entries in the cache directory will be removed.

Returns `Promise<void>` - resolves when the code cache clear operation is complete.

#### `ses.setSpellCheckerEnabled(enable)`

* `enable` boolean
Expand Down
42 changes: 42 additions & 0 deletions shell/browser/api/electron_api_session.cc
Expand Up @@ -28,6 +28,7 @@
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/proxy_config/proxy_prefs.h"
#include "content/browser/code_cache/generated_code_cache_context.h" // nogncheck
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item_utils.h"
Expand Down Expand Up @@ -976,6 +977,45 @@ v8::Local<v8::Value> Session::GetPath(v8::Isolate* isolate) {
return gin::ConvertToV8(isolate, browser_context_->GetPath());
}

void Session::SetCodeCachePath(gin::Arguments* args) {
base::FilePath code_cache_path;
auto* storage_partition = browser_context_->GetDefaultStoragePartition();
auto* code_cache_context = storage_partition->GetGeneratedCodeCacheContext();
if (code_cache_context) {
if (!args->GetNext(&code_cache_path) || !code_cache_path.IsAbsolute()) {
args->ThrowTypeError(
"Absolute path must be provided to store code cache.");
return;
}
code_cache_context->Initialize(
code_cache_path, 0 /* allows disk_cache to choose the size */);
}
}

v8::Local<v8::Promise> Session::ClearCodeCaches(
const gin_helper::Dictionary& options) {
auto* isolate = JavascriptEnvironment::GetIsolate();
gin_helper::Promise<void> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();

std::set<GURL> url_list;
base::RepeatingCallback<bool(const GURL&)> url_matcher = base::NullCallback();
if (options.Get("urls", &url_list) && !url_list.empty()) {
url_matcher = base::BindRepeating(
[](const std::set<GURL>& url_list, const GURL& url) {
return base::Contains(url_list, url);
},
url_list);
}

browser_context_->GetDefaultStoragePartition()->ClearCodeCaches(
base::Time(), base::Time::Max(), url_matcher,
base::BindOnce(gin_helper::Promise<void>::ResolvePromise,
std::move(promise)));

return handle;
}

#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
base::Value Session::GetSpellCheckerLanguages() {
return browser_context_->prefs()
Expand Down Expand Up @@ -1203,6 +1243,8 @@ gin::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
.SetMethod("preconnect", &Session::Preconnect)
.SetMethod("closeAllConnections", &Session::CloseAllConnections)
.SetMethod("getStoragePath", &Session::GetPath)
.SetMethod("setCodeCachePath", &Session::SetCodeCachePath)
.SetMethod("clearCodeCaches", &Session::ClearCodeCaches)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("netLog", &Session::NetLog)
.SetProperty("protocol", &Session::Protocol)
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/api/electron_api_session.h
Expand Up @@ -127,6 +127,8 @@ class Session : public gin::Wrappable<Session>,
void Preconnect(const gin_helper::Dictionary& options, gin::Arguments* args);
v8::Local<v8::Promise> CloseAllConnections();
v8::Local<v8::Value> GetPath(v8::Isolate* isolate);
void SetCodeCachePath(gin::Arguments* args);
v8::Local<v8::Promise> ClearCodeCaches(const gin_helper::Dictionary& options);
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
base::Value GetSpellCheckerLanguages();
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
Expand Down
14 changes: 14 additions & 0 deletions spec-main/api-session-spec.ts
Expand Up @@ -1121,6 +1121,20 @@ describe('session module', () => {
});
});

describe('session.setCodeCachePath()', () => {
it('throws when relative or empty path is provided', () => {
expect(() => {
session.defaultSession.setCodeCachePath('../fixtures');
}).to.throw('Absolute path must be provided to store code cache.');
expect(() => {
session.defaultSession.setCodeCachePath('');
}).to.throw('Absolute path must be provided to store code cache.');
expect(() => {
session.defaultSession.setCodeCachePath(path.join(app.getPath('userData'), 'test-code-cache'));
}).to.not.throw();
});
});

describe('ses.setSSLConfig()', () => {
it('can disable cipher suites', async () => {
const ses = session.fromPartition('' + Math.random());
Expand Down