lambdadog / passfail2

Pass/Fail addon for Anki
GNU General Public License v3.0
21 stars 2 forks source link

v3 Scheduler causes infinite session when using Custom Study #8

Open Xelieu opened 1 year ago

Xelieu commented 1 year ago

I usually do custom study > Forgotten cards for the last x day

With pass-fail I noticed that even if you click the default 1 or 2, well even up to 3 and 4 which is supposedly hidden, the custom study deck never gets finished, it is just stuck as 'learning' or the orange number thingy.

I tried switching between v2 or v3, doesn't seem to be problem, but when I went back to 2.1.49 the behavior also went back to normal.

lambdadog commented 1 year ago

Ah, that's not good. Thanks for bringing this to my attention.

For now I've set the supported version range on AnkiWeb to only go to 49, but I'll debug as soon as I've gotten the chance.

lambdadog commented 1 year ago

Okay, so I've been able to get around to this and I haven't been able to reproduce it. I don't currently use Anki for anything so I can't do the exact same Custom Study you have -- I have no forgotten cards in the last 30 (maximum value) days to draw on -- but I've tried the other Custom Study settings in Anki 2.1.50 and 2.1.56 and I haven't had any issues completing them.

Are there any other addons you have installed that could be causing the problem? Pass/Fail 2 is really an incredibly light addon that only interacts with the interface, and I wouldn't expect it to be able to cause this kind of issue.

I've done some digging around in the code changes between 2.1.49 and 2.1.50 too, and there doesn't seem to be anything that could be causing any issues with the functionality of the addon. I obviously can't say this completely conclusively given the size and complexity of Anki, but given the size of the addon and that it only interacts with functions in one file (qt/aqt/reviewer.py) I'd be surprised to learn there's something I missed.

Xelieu commented 1 year ago

I really believe this is a bug as I've been experiencing this for months, though I could've missed something out too.

Versions I've tried is 2.1.49, 2.1.55Qt6 and 2.1.56Qt5, I've only mentioned it starts from 2.1.50+ because I assumed its mostly the same up to .56

Anyways with 2.1.56Qt5, all add-ons disabled(I restarted my Anki) and v3 scheduler, I've made a video to reproduce the issue: https://youtu.be/Obs1_4mXPrQ (sorry for JP, but its pretty much forgotten x day/s)

I also tried cycling it as a whole as is: if in the video its 98 cards, I tried passing that 98x5 with the same result, it is stuck as 'learning'

lambdadog commented 1 year ago

Ahhh, I see what is happening and how this could be the fault of Pass/Fail 2. Somehow, either the custom study handles the ease values Pass/Fail 2 returns differently or PF2 is making a bad assumption that the custom study breaks (_defaultEase being a "fail" perhaps, in this study mode? requires investigation)

I suspect I may have to take a somewhat deeper dive into the recent changes in Anki tomorrow. Thank you for the video, that cleared up the issue quite a bit.

Xelieu commented 1 year ago

For additional info since its on JP: even before it goes to 'learning' or orange number thingy, the pass button already says 'after 20mins', which I assume wouldn't be the case if it was connected to the right logic, though even going into 'learning phase' the same button has the same amount of time which is 20mins after, meaning it was the same logic no matter what, also tested space, 3 and 4 buttons having the same behavior, idk how much that would help but you're probably right with your guess

I've also tested without the add-on, I've only unhide my time for this video so I didn't noticed(my bad), the '20 mins after' button is actually the 'good' button, while the 'easy' button became the 'pass' button, if the issue is as simple as this, I guess the approach would be the normal study keybinding would remain the same, while custom study needs to be keybinded to 'easy' button? Well idk how you would if-else custom study but thanks for the effort!

lambdadog commented 1 year ago

I believe you're right about this. This would mean that the custom study uses different logic for the ease values, somehow.

I tried switching between v2 or v3, doesn't seem to be problem, but when I went back to 2.1.49 the behavior also went back to normal.

To clarify for this, do you mean that when you used the v2 scheduler and a custom study in 2.1.56, you still ran into this issue? I'm trying to identify exactly where the logic is in the code to try and ensure PF2 retains correct behavior without simply hardcoding this special case.

So far all I've been able to find on how custom studies are configured is by creating a filtered deck and just running a study on them:

// anki/rslib/src/scheduler/filtered/custom_study.rs
fn custom_study_config(
    reschedule: bool,
    search: String,
    order: FilteredSearchOrder,
    limit: Option<u32>,
) -> FilteredDeck {
    FilteredDeck {
        reschedule,
        search_terms: vec![FilteredSearchTerm {
            search,
            limit: limit.unwrap_or(99_999),
            order: order as i32,
        }],
        delays: vec![],
        preview_delay: 10,
    }
}

fn forgot_config(deck_name: String, days: u32) -> FilteredDeck {
    let search = SearchNode::Rated {
        days,
        ease: RatingKind::AnswerButton(1),
    }
    .and(SearchNode::from_deck_name(&deck_name))
    .write();
    custom_study_config(false, search, FilteredSearchOrder::Random, None)
}

So, the "forgotten" custom study simply runs a search for cards which you've answered "again" in the last X days, creating a filtered deck with it.

I'm going to deep dive in the code a bit more to see if I can hunt this behavior down.

lambdadog commented 1 year ago

I have a suspicion that this may have something to do with the v3 scheduler being more advanced and I may need to poke into this functionality: Add-ons and Custom Scheduling

At least in a read-only matter, to allow me to evaluate which button to select as "Pass" dynamically.

Still not entirely sure about this, though.

lambdadog commented 1 year ago

Aha, as a matter of fact, one of the potential scheduling states a card can be in is "Filtered" which may be the cause of this, presuming this isn't broken on the v2 scheduler as well?

Pass/Fail 2 is, however, built on an understanding of the v2 scheduler -- it may be worth re-evaluating the add-on as a whole and ensuring that its goals are still being reached with the v3 scheduler.

I still certainly believe that a simple binary Pass/Fail choice is better than the entire range that Anki offers, but if the v3 scheduler means the "Good" button doesn't always behave the same as it would in v2 then the Pass button's behavior may not be entirely correct.

Xelieu commented 1 year ago

I guess you are right about v2 and v3 difference after retesting said schedulers, my bad my memory didn't serve me well, though if I had a choice I'd go back to v2, but currently the 2.1.5.5 'custom scheduler' feature update is really good and I finally bit the bullet, if binary is the best, then I guess the easiest solution would be a specific add-on for v3? Thanks for finding solution to this so far, I don't know about anki add-ons personally otherwise I'd try tinkering about them, but I can't really live without the pass/fail 2 haha.

lambdadog commented 1 year ago

I should be able to just integrate it into the current addon and have it detect whether you're using the v2 or v3 scheduler at runtime, but the big issue will be understanding the v3 scheduler well enough to feel confident in an implementation.

For the time being I want to take a day or two more of working through the Anki code so I feel confident in my conclusion, then I will begin work on the v3 implementation of Pass/Fail 2.

Thank you for bringing this to my attention! I'm glad Pass/Fail 2 has been helpful to your studies and I hope it can be helpful for your studies again soon when I'm able to implement v3.

lambdadog commented 1 year ago

Ah, hm. It's funny, I may have found the main issue, and I skimmed over it several times.

In the "The 2021 scheduler" page of the Anki FAQ it says this:

Filtered decks

Filtered decks with rescheduling disabled now show 4 buttons - the provided delay applies to the Again button, and Hard/Good will use 1.5x and 2x the provided delay. Easy will remove the card.

This meaning "Good" will never remove the card, as just a hardcoded piece of functionality.

If this is the case, preliminary implementation just become much easier, assuming we want Pass to just remove the card from the study as Easy does.

This means that it may be possible to simply insert something like the following javascript into the view and make things work?

if (states.good.filtered?.preview) {
  states.good.filtered?.preview.scheduled_secs = 0;
  states.good.filtered?.preview.finished = true;
}

It's still worthwhile to evaluate the v3 scheduler and I'm not 100% sure Pass should immediately remove the card, but this would fix it fairly trivially.

lambdadog commented 1 year ago

Ah, it's notably not super trivial to do that automatically -- Anki for some reason doesn't expose that field to addons very well, instead opting to just let it be a user field at the bottom of the deck options page.

The best solution may be to use Anki's monkey-patching facilities to wrap _run_state_mutation_hook. For now I need to get some rest however, so I will return to this problem tomorrow.

lambdadog commented 1 year ago

(I have created this suggestion on the Anki forums which will enable a better way to do this: https://forums.ankiweb.net/t/enable-addon-access-to-v3-scheduling-states-without-monkey-patching/26708)

Xelieu commented 1 year ago

Thanks for your hard work!

It's still worthwhile to evaluate the v3 scheduler and I'm not 100% sure Pass should immediately remove the card, but this would fix it fairly trivially.

I think this solution is the right one, at least for my use case of custom study is that 'reschedule cards' is unchecked, meaning no matter the intervals or if it passed immediately it doesn't matter, it is sort of a review function for me, same thing on normal study, its either I don't know or I know stuff, so after custom study the deck is unaffected

Though I guess for normal use-case if you want it rescheduled is, the easy remove refers to just having it 'passed' and out of custom study + intervals applied rather than actually removing it from the deck, while good and hard is just the additional time interval required for you to see it again on that same custom study, at least from how I understood it.

If above is true, normal ones is useful but that's not the point of pass/fail anyway