← Back to team overview

ubuntu-accomplishments-contributors team mailing list archive

Re: Maintaining State

 

Using a queue for scheduling tasks for the scriptrunner seems as a good
trick, yet I guess our main problem is that we rely on some global
variables, mainly "self.parent.scriptrun_results", which Jono has mentioned
in his last message. This may indeed lead to troubles if the scriptrunner
runs several times before a trophy is validated.

A quick explanation of why the problem emerges, for those who are not into
exact implementation:
The idea behind scriptrun_results is to display only one notification
bubble for each "group" of simultanously achieved accomplishments (at least
that's how it looks from the source code).
Whole that concept is expected to work that way: whenever ANY trophy gets
validated, check whether the scriptsrunner has finished it's work, and if
yes, prepare a list of ALL new accomplishments that are unlocked by all
accomplishments that the scriptrunner has recently reported as
just-accomplished (but likely not yet verified).
The trouble: If the scriptrunner is run before trophies are verified, all
these global variables that store the list of 'just-accomplished'
accomplishments are reset (well, not exactly reset, but that's not
necessary to explain in order to get an idea of the problem), and therefore
we loose our information about what scriptrunner did in it's last run, and
are unable to display information about unlocked accomplishments.

The above concept is mainly fine, but only provided that the scriptrunner
is run 'rarely' - it would have to postpone running after a notification
about unlocked accomplishments is show, otherwise we loose that information.
But even there this have issues. And I guess changing the way we maintain
scriptrunners state will not help much.

First thing is, that we cannot assume all accomplishments will be validated
at once. The idea behind validation is to prevent user from cheating etc.,
so we have to remember, that it may happen that the .asc file verifying a
trophy will *never* arrive. This means that if we want to 'group' the
'unlocked n trophies bubble' to contain information concerning all
accomplishments that were verified locally on last scriptrunner's
execution, the daemon would have to wait untill ALL these trophies get a
.asc file, and then notify the user about unlocks - but it may happen these
.asc files will never be get.
Another case is U1 lagging from time to time. Imagine situation when a user
accomplishes two accomplishments, A and B. A unlocks 1 new acc, B unlocks
100. They are send to verification, A.asc is got immediately, B.asc not -
the user will have to wait several minutes/hours. As soon as A.asc is got,
the daemon displays "You have unlocked 101 new accomplishments" - because
that number originates from it's own, local verification.The user gets
cheered up, opens the viewer... but there is only 1 new accomplishment
unlocked.
Also, notice that treating all simultaneously verified locally
accomplishments as a group makes little sense, because some of these that
just got unlocked have *already been* accomplished, and should also be
awarded in the same group.

This leads me to conclusion that grouping accomplishments that are verified
by an external server will always be unsure to work properly, because it's
based on unsure assumptions. Does that mean that our current way of
displaying unlock notifications makes no sense?

Do notice that for an average user a situation where
multiple accomplishments are achieved at once is vary rare, it happens to
us a lot while testing, but that's not a common case, so I believe an
elegant way of dealing with multiple trophies being verified in a shot time
is definitely not a high priority feature.


My suggestion is to abandon scriptrun_results etc. at all. It's only
purpose is to display bubbles "you have unlocked ..." only once per group
of simultaneously achieved accomplishments, which - as I hope to have
proved above - is usually not a good idea, may lead to confusion and even
display incorrect information.
A much easier approach that would solve problems with scriptrunner's state
is to calculate unlocks for each verified accomplishment independently.
Using the same example as above, that would mean when A.asc arrives, we
determine how many new accomplishments are unlocked (1), completelly
ignoring the fact that scriptrunner has detected that B was also
accomplished. We will display information about B unlocking 100 new
accomplishments when we'll get B.asc, which may be soon after, a longer
time after, or maybe never.
This way we always display true information, based on what is verified by
the server, and not just checked locally.
Also, we do not have to worry about scriptrunner's state at all, it can
even be running while we determine new, unlocked accomplishments. The whole
process of unlocking anything is completely independent from scripts. Not
to mention that this solution might slightly simplify the API a bit, as a
side-effect.
Another advantage is that daemon's behavior would then be a bit more
predictable and logical - the algorithm becomes: when a .asc arrives, check
if that particular accomplishments unlocks anything else, and if it
does, immediately display a bubble, notifying the number of unlocks.
Does that make sense?

Also I need to say that I am not against displaying grouped information,
this in fact would look much nicer - but I am convinced that with our
current system architecture this would be very wrong in most cases.


And finally concerning consumer-producer model - While this will not solve
the problem with current race condition, this is a very elegant way of
managing tasks for the scriptrunner - I believe this way it would be much
easier to control it, and to maintain it's performance. If Jono agrees, I
might try implementing that for 0.2 as a part of refined API.


I hope my points are clear and make some sense.

Follow ups

References