Feature #4556

Non-blocking requests for org.simantics.db.Session

Added by Tuukka Lehtonen almost 4 years ago. Updated over 2 years ago.

Status:ClosedStart date:2013-11-18
Priority:4Due date:2015-05-21
Assignee:Tuukka Lehtonen% Done:

100%

Category:-Spent time:3.00 hours
Target version:1.18.1
Release notes:Implemented simple non-blocking (timeouting) synchronous database request facilities on top of the existing database API. This allows implementing certain UI functionality, such as platform PropertyTesters in a much less blocking manner to keep the UI more responsive even if the database does not respond.
Tags: db
Story pointsS
Velocity based estimate-
ReleaseSimantics 1.18.1Release relationshipAuto

Description

See #3861 for the original problems related to this issue.

In order to support potentially performing database requests in places where the calling code must not block execution indefinitely, database sessions would require a mechanism for trying to perform a request with a specified timeout. The timeout could be specified as 0, in which case the request would be totally non-blocking, i.e. return immediately if it can't execute the request immediately.

DatabaseJob was introduced in November 2012 as one kind of workaround for the whole UI-blockage issue.


Related issues

Related to Platform - Bug #3861: Make the platform support running of medium-long/long dat... Closed
Related to Platform - Enhancement #5839: Timeouting (non-blocking) database requests for platform ... Closed 2015-05-12 2015-05-21
Related to Platform - Enhancement #5840: Introduce a Runnable interface that indicate read-only ta... Closed 2015-05-12 2015-05-21

Associated revisions

Revision 31273
Added by Tuukka Lehtonen over 2 years ago

Introduced org.simantics.db.common.utils.RequestUtil to implement timeouting (sort-of-non-blocking) synchronous database request support.

    public static final <R> R trySyncRequest(
            Session session,
            long requestStartTimeout,
            long requestExecutionTimeout,
            R timeoutResult,
            final Read<R> read,
            final Procedure<R> procedure)
                    throws DatabaseException, InterruptedException

The utility inteface has two separate timeouts, one for actually starting execution of the request and one for the time it takes to complete the request execution.
A negative completion timeout can be specified to indicate no completion timeout.
The interface also allows the client to specify the value to be returned incase timeout occurs.

refs #4556

Revision 31278
Added by Tuukka Lehtonen over 2 years ago

Merged trunk@31273 to branches/simantics-1.18 on 2015-05-12 for 1.18.2 release.

refs #4556

History

#1 Updated by Tuukka Lehtonen almost 4 years ago

Aivan vesiselvä ja kaikenkattava ei ratkaisu tunnu minusta olevan edes non-blocking I/O:lla. Tarkastellaan esimerkkinä PropertyTestereitä, jotka useimmiten noi UI:n jumitukset ovat aiheuttaneet.
Nyt siellä on jotain tämänkaltaista koodia:

        if (DatabaseJob.inProgress())
            return false;
        try {
            return ctx.getSession().syncRequest(new Read<Boolean>() { ...

Ajatellaan, että vaihdettaisi tuo koodi seuraavanlaiseksi:

        try {
            Boolean result = ctx.getSession().trySyncRequest(0, new Read<Boolean>() { 
            ...

DatabaseJob-checkin voisi myös jättää paikalleen trySyncRequestista huolimatta. Se ei kuitenkaan poista seuraavia ongelmia. Muutettu koodi siis yrittäisi laskea tuloksen vain jos pystyy tekemään sen välittömästi. Jos sovelluksessa sattuu olemaan esimerkiksi jokin editori auki tai muu mekanismi, joka tekee jatkuvasti transaktioita, voi käydä niin, että PropertyTesterit "nälkiintyvät" eivätkä koskaan saa requestejaan läpi. Toisaalta, hyvin lyhyen timeoutin käyttäminen saattaa ratkaista ongelman, mutta vakio-timeout voi erilaisten ympäristöjen suorituskyvystä riippuen olla hieman epästabiili ratkaisu. Tottakai nykyinen ratkaisu, jossa odotetaan loputtomiin on huonompi kuin ei timeouttia ollenkaan. Riippuen extensionien ja niiden testerimääritysten määrästä PropertyTestereitä saatetaan kutsua useimpien UI-interaktioiden jälkeen kymmeniä kertoja. Isommalla vakio-timeoutilla (esim 10-100ms), jos jokaisessa niissä vaikka joudutaan pahimmillaan odottelemaan vaikka koko timeuotin ajan, menee UI aika tukkoon joka tapauksessa.

Ehkä tästä vois vetää sen johtopäätöksen, että pieni timeout (1-5 ms) olisi järkevin ensimmäinen kokeilu. Täysin non-blockingina UI:sta alkaa putoilla kontribuutioita pois käyttäjän kannalta satunnaisen oloisesti. Pitkällä aikavälillä rinnakkaiset luvut auttaisivat tietenkin myös tilannetta.

#2 Updated by Antti Villberg almost 4 years ago

Tuukan kuvaaman trySyncRequest-rajapinnan voi toteuttaa nykyisen asyncRequest - kutsun päälle siten, että skeduloidaan kysely ja jäädään odottelemaan sen valmistumista tietyksi ajaksi. Jos sitten aika menee umpeen niin merkitään request siten, ettei se suorituseen päästyään tee mitään. Tekisin testit tällä tavoin ja jos sitten konsepti on toimiva niin voidaan miettiä, että pitäisikö vastaava metodi tehdä suoraan session rajapinnalle.

#3 Updated by Tuukka Lehtonen over 2 years ago

  • Tags set to db
  • Due date set to 2015-05-21
  • Status changed from New to Feedback
  • Assignee set to Tuukka Lehtonen
  • Target version set to 1.18.2
  • % Done changed from 0 to 100
  • Release set to 33

Antti Villberg wrote:

Tuukan kuvaaman trySyncRequest-rajapinnan voi toteuttaa nykyisen asyncRequest - kutsun päälle siten, että skeduloidaan kysely ja jäädään odottelemaan sen valmistumista tietyksi ajaksi. Jos sitten aika menee umpeen niin merkitään request siten, ettei se suorituseen päästyään tee mitään. Tekisin testit tällä tavoin ja jos sitten konsepti on toimiva niin voidaan miettiä, että pitäisikö vastaava metodi tehdä suoraan session rajapinnalle.

r31273 provides the implementation suggested by Antti, i.e. building a synchronous timeouting request on top of asyncRequest(). Later we can do better but for now this covers our needs for implementing property tester logic with timeouts.

#4 Updated by Tuukka Lehtonen over 2 years ago

  • Target version changed from 1.18.2 to 1.18.1
  • Release changed from 33 to 17
  • Release notes set to Implemented simple non-blocking (timeouting) synchronous database request facilities on top of the existing database API. This allows implementing certain UI functionality, such as platform PropertyTesters in a much less blocking manner to keep the UI more responsive even if the database does not respond.

#5 Updated by Tuukka Lehtonen over 2 years ago

  • Status changed from Feedback to Closed

Also available in: Atom PDF