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

Fix v2.8.1 saving issues #1473

Merged
merged 19 commits into from
Oct 29, 2021
Merged

Fix v2.8.1 saving issues #1473

merged 19 commits into from
Oct 29, 2021

Conversation

harshad1
Copy link
Collaborator

@harshad1 harshad1 commented Oct 20, 2021

  • Merge Document and DocumentIO classes, debloat
  • flush() after write()
  • less save/read calls in activitiy lifecycle
  • ..

@harshad1 harshad1 changed the title Added a flush to save Fixing loss of last line Oct 20, 2021
@gsantner gsantner added this to the 2.9 milestone Oct 20, 2021
@gsantner gsantner added the bug label Oct 20, 2021
@harshad1
Copy link
Collaborator Author

Issue is that the file is not written before it is read.

The text sent to disk in onPause is not the same as the text which is read in onResume. If you wait 10s, the process succeeds.

@gsantner
Copy link
Owner

merge it now and release update right away?

@harshad1
Copy link
Collaborator Author

harshad1 commented Oct 21, 2021 via email

@gsantner
Copy link
Owner

I think we numerous times reworked file saving but might be the time we need to completly rethink it. Though it's a lot of work, and prone to produce more issues.

@harshad1
Copy link
Collaborator Author

harshad1 commented Oct 21, 2021

This issue is weirder than I thought.

  1. Open file
  2. Add text
  3. Switch apps
  4. Open file in other editor <- new text present (can even be another instance of markor!)
  5. Open markor again <- new text gone

@gsantner
Copy link
Owner

then maybe cached string in Document, saveinstancestate or textview?

@harshad1
Copy link
Collaborator Author

Stranger yet:

  1. Insert lines in the middle of a file
  2. Switch apps
  3. Switch back
  4. Some lines from the end are missing

@harshad1
Copy link
Collaborator Author

What are the uses of the Document class exactly? It seems to support undo / redo... but TextViewUndoRedo also does that?

@gsantner
Copy link
Owner

gsantner commented Oct 22, 2021

I wrote DocumentIO stuff from scratch, including undo/redo history, file saving etc. Over time most stuff got replaced by other means (i.e. undo/redo worked better in the said textview class)

@harshad1
Copy link
Collaborator Author

https://medium.com/androiddevelopers/android-11-storage-faq-78cefea52b7c

The OS maintains a system to attribute an app to each media store file, so apps can read/write files that they originally contributed to the Media Store without needing storage permissions.

I wonder if these are affecting us

@gsantner
Copy link
Owner

gsantner commented Oct 23, 2021

I don't think so it is the issue. Because Android 11 is out some time now and Markor users, including me have used Markor on it for quite a long time without the issue.

Btw, could you spot any issue coming from either the cached FileInfo used at filemanager, or the dynamically fetched own FileProvider? These two things are new in Markor v2.8.1. Though the first is only used at filemanager and not has any writing stuff. And the latter also shoule be fine.

@harshad1
Copy link
Collaborator Author

This has evolved into a refactor of Document and DocumentIO.

Changes:

  1. Document does not store content, only a hash of content if it is necessary to check if the content matches (need to change to a non-cryptographic hash)
  2. DocumentIO has been removed. Document now has save and read methods
  3. Most of the read / save logic has been ported as-is. But several changes have been made

Obviously a lot of testing will have to be performed before this is ready. On the bright side, the bug with missing text appears to have gone away?

assertThat(normalizeTitleForFilename(nd("HelloWorld", "text"))).isEqualTo("HelloWorld");
assertThat(normalizeTitleForFilename(nd(null, "text\nnewline"))).isEqualTo("text");
assertThat(normalizeTitleForFilename(nd(null, "sumtext/folder"))).isEqualTo("sumtextfolder");
assertThat(normalizeTitleForFilename(nd(null, "## hello world"))).isEqualTo("hello world");
Copy link
Collaborator Author

@harshad1 harshad1 Oct 24, 2021

Choose a reason for hiding this comment

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

  • Need to restore this test

Comment on lines 358 to 363
public static String normalizeFilename(final String name) {
if (TextUtils.isEmpty(name.trim())) {
return "Note " + UUID.randomUUID().toString();
} else {
return name.replaceAll("[\\\\/:\"´`'*$?<>\n\r@|#]+", "").trim();
}
Copy link
Owner

Choose a reason for hiding this comment

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

needs discussion/change before merge. as this is about to be used everywhere for filenames.

suggestion: R.string ("Note" localized) + DateTime YYYY-MM-DD_HHMMSS or something alike

https://stackoverflow.com/a/35352640

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The code there was derived from

https://github.com/gsantner/markor/blob/master/app/src/main/java/net/gsantner/markor/util/DocumentIO.java#L227

Your suggestion here is better IMO. datetime is better than uuid. I will make the change this evening.

@gsantner
Copy link
Owner

@harshad1
Other than "automatic filename" and "test cases", it's mergeable to my view. What do you think?

@harshad1
Copy link
Collaborator Author

harshad1 commented Oct 27, 2021

@harshad1 Other than "automatic filename" and "test cases", it's mergeable to my view. What do you think?

I think it is good to go. I have been using this branch for the last 2 days without any issues.

Will made the changes for tests, for the uuid -> datetime change today. We can then merge tomorrow I think.

@gsantner
Copy link
Owner

Thanks, I want to merge it on the weekend

@gsantner
Copy link
Owner

gsantner commented Oct 28, 2021

@harshad1

I can see that it shortly blinks when swiping the tabs. So looks like it reloaded the file fully and overwrote the textview content, though it's would not be necessary.

screenrecord.mp4

I didn't change any text in editor, but landed in the writing code:

grafik

}

public int getHistoryPosition() {
return _historyPosition;
public static boolean testCreateParent(final File file) {
Copy link
Owner

@gsantner gsantner Oct 28, 2021

Choose a reason for hiding this comment

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

this won't work for sdcard, would always returns false when parents not exist.
I ignore it though to get the PR merged fast.

* reload file only if newer modtime (skip unnecassary read operations)
* rework SHA512 hashfunction to return a printable hash string (instead of bytes.toString)
* fix check to non-duplicate saving code check from: hashunchanged && notWrittenShortlyAgo to ||
@harshad1
Copy link
Collaborator Author

harshad1 commented Oct 28, 2021

Both scenarios are known / expected.

case 1: The content being reloaded when not needed.

When we switch tabs (or restore a document which is in the background) we need to check if the file contents has changes. If it has changed we need to update the contents, and if there is no change we can just set the contents anyway as the loaded contents == the existing data. We can test if the loaded text == current text if preventing the flash is important.

case 2: I didn't change any text in editor, but landed in the writing code.

The write is blocked if and only if the same text was written recently (i.e. time delta < small threshold). This was done to ensure that the file seen in the text editor == the contents written to disk.

If the text has been changed in the background (by a sync app, for example), I felt that that the correct thing to do is to always write the text as seen in the editor.

We can use modtime to be more defensive here.

@gsantner
Copy link
Owner

@harshad1 I did some improvements to reduce the amount of file write and file read calls, to have no/less unecessary multiple reads/writes.
Can you spot some issue with my changes?

it also makes use of the modtime, as you mentioned in 2)

@harshad1
Copy link
Collaborator Author

Seems ok. But I will test more in the evening.

@gsantner
Copy link
Owner

Merging this now and asking users once more to try it as well. "release candidate"

@gsantner gsantner merged commit 07c584e into gsantner:master Oct 29, 2021
@gsantner gsantner self-assigned this Oct 29, 2021
@harshad1
Copy link
Collaborator Author

Cool.

Another (probably unrelated) issue that I have noticed is that onPause / onResume / onViewCreated in DocumentEditFragment are called 2x. We need to investigate this as well.

@harshad1
Copy link
Collaborator Author

Possible cause for ^ https://stackoverflow.com/a/49679530/4717438

@gsantner
Copy link
Owner

when you are on mainactivity, or editor?

on main its due each of quicknote and todo.txt own lifecycle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

v2.8.1 update: Saving issues
2 participants