Skip to content

Miduo/224 optimize login latecy#606

Open
Miduo666 wants to merge 3 commits intoanusii:devfrom
Miduo666:miduo/224_optimize_login_latecy
Open

Miduo/224 optimize login latecy#606
Miduo666 wants to merge 3 commits intoanusii:devfrom
Miduo666:miduo/224_optimize_login_latecy

Conversation

@Miduo666
Copy link
Contributor

@Miduo666 Miduo666 commented Mar 2, 2026

Pull Request Details

What issue does this PR address

  • [Description]

Associated Issue

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist

Complete the check-list below to ensure your branch is ready for PR.

  • Screenshots included in linked issue #
  • Changes adhere to the style and coding guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • Any dependent changes have been merged and published in downstream modules
  • The update contains no confidential information
  • The update has no duplicated content
  • No lint check errors are related to these changes (make prep or flutter analyze lib)
  • Integration test dart test output or screenshot included in issue #
  • I tested the PR on these devices:
    • Android
    • iOS
    • Linux
    • MacOS
    • Windows
    • Web
  • I have identified reviewers
  • The PR has been approved by reviewers

Finalising

Once PR discussion is complete and reviewers have approved:

  • Merge dev into the this branch
  • Resolve any conflicts
  • Add a one line summary into the CHANGELOG.md
  • Push to the git repository and review
  • Merge the PR into dev

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets issue #224 by reducing perceived login/initialization latency in the Solid POD client codepaths, primarily by introducing in-memory caching and parallelizing URL resolution/resource creation.

Changes:

  • Speed up initPod() by parallelizing URL resolution and concurrent file creation, and by avoiding unnecessary regeneration when lists are explicitly provided.
  • Add in-memory caches for token responses and profile card data to reduce repeated deserialization/JWT checks and repeated profile fetches.
  • Minor import-order/formatting cleanups in the example app.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
lib/src/solid/utils/init_helper.dart Parallel URL resolution + concurrent file creation; new encryption setup flow.
lib/src/solid/utils/authdata_manager.dart Adds in-memory token and profile caches; clears caches on logout.
lib/src/solid/authenticate.dart Adds optional wasAlreadyLoggedIn; reuses cached issuer/profile data to avoid redundant GETs.
example/lib/utils/rdf.dart Import/whitespace cleanup.
example/lib/main.dart Import ordering cleanup.
example/lib/features/view_keys.dart Import ordering cleanup.
example/lib/features/file_service.dart Import ordering cleanup.
example/lib/features/edit_keyvalue.dart Import ordering cleanup.
example/lib/features/create_acl_inherited_file.dart Import ordering cleanup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 205 to +280
@@ -208,62 +237,92 @@ Future<void> initPod(
}

// Check (and generate) the file URLs.
// Only regenerate when the caller did not provide any list (null).
// An empty list means "no files to create" and should be respected.

if (fileUrls == null || fileUrls.isEmpty) {
if (fileUrls == null) {
final defaultFiles = await generateDefaultFiles();
fileUrls = <String>[];
// Resolve all file URLs in parallel — each call reads the cached webId.
final urlFutures = <Future<String>>[];
for (final entry in defaultFiles.entries) {
final d = entry.key;
final d = entry.key as String;
for (final f in entry.value as List) {
fileUrls.add([d, f].join('/'));
urlFutures.add(getFileUrl([d, f as String].join('/')));
}
}
fileUrls = await Future.wait(urlFutures);
}

// Create the encKeyFile, indKeyFile and pubKeyFile
// and remove them from the fileUrls list.

await KeyManager.initPodKeys(securityKey);
fileUrls.remove(await getFileUrl(await getEncKeyPath()));
fileUrls.remove(await getFileUrl(await getIndKeyPath()));
fileUrls.remove(await getFileUrl(await getPubKeyPath()));

for (final f in fileUrls) {
final fileName = f.split('/').last;
late String fileContent;
late bool aclFlag;

if (f.split('.').last == 'acl') {
final items = f.split('.');
final resourceUrl = items.getRange(0, items.length - 1).join('.');
late Set<AccessMode> publicAccess;
var isFile = true;
switch (fileName) {
case '$pubKeyFile.acl':
publicAccess = {AccessMode.read};
case '$permLogFile.acl':
publicAccess = {AccessMode.append};
default:
assert(fileName == '.acl');
publicAccess = {AccessMode.read, AccessMode.write};
isFile = false;
}
// Handle encryption key setup.

fileContent = await genAclTurtle(
resourceUrl,
isFile: isFile,
publicAccess: publicAccess,
);
if (needsEncSetup) {
// First-time setup: create encryption key files from scratch.

aclFlag = true;
} else {
assert(fileName == permLogFile);
fileContent = genPermLogTTLStr(f);
aclFlag = false;
}
await KeyManager.initPodKeys(securityKey);
} else {
// Encryption already initialised: just verify and set the security key
// so that encrypted operations work in this session without overwriting
// existing keys.

await createResource(f, content: fileContent, replaceIfExist: aclFlag);
await KeyManager.setSecurityKey(securityKey);
}

// Remove encryption key file URLs from the list (already handled above).
// Resolve all three key paths in parallel, then remove them from the list.

final encKeyUrls = await Future.wait([
getEncKeyPath().then(getFileUrl),
getIndKeyPath().then(getFileUrl),
getPubKeyPath().then(getFileUrl),
]);
for (final url in encKeyUrls) {
fileUrls.remove(url);
}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needsEncSetup is decided based on whether the encryption directory is in dirUrls or exists on the server, but key-file existence isn’t checked. When needsEncSetup is false you still remove the enc/ind/pub key URLs from fileUrls, so if any of those key files are missing/corrupt while the directory exists, initPod will neither recreate them nor include them in the subsequent createResource loop, and KeyManager.setSecurityKey() may fail when it tries to load/verify keys. Consider determining needsEncSetup by checking the status of the key files themselves (or falling back to initPodKeys on setSecurityKey failure) and only removing key URLs when you actually handle them via KeyManager.

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +129
var profData = getCachedIssuerProfileBody(profCardUrl);
// If the issuer was resolved from a plain URI (not a WebID profile URL),
// the profile body was not pre-fetched. Fetch it now with the
// authenticated access token.
profData ??= utf8.decode(await getResource(profCardUrl));
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getCachedIssuerProfileBody() is referenced here but there is no definition in this repository. If this relies on package:solid_auth exporting that API, please ensure the minimum solid_auth version in pubspec actually includes it (otherwise consumers pinned to 0.1.28 will fail to compile), or add a local implementation/abstraction within this package.

Copilot uses AI. Check for mistakes.
Comment on lines +297 to +306
switch (fileName) {
case '$pubKeyFile.acl':
publicAccess = {AccessMode.read};
case '$permLogFile.acl':
publicAccess = {AccessMode.append};
default:
assert(fileName == '.acl');
publicAccess = {AccessMode.read, AccessMode.write};
isFile = false;
}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switch over fileName is missing terminating statements (break/return/continue) for the first two cases. In Dart this is either a compile-time error or will behave as unintended fall-through (setting publicAccess/isFile incorrectly). Add explicit termination for each case (or rewrite as an if/else or switch expression) so each ACL file gets the intended permissions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants