Foutcode itgenboe147 na 5 minuten

Sinds een paar dagen krijg ik in Power BI een foutmelding itgenboe147 bij het herladen van het dashboard. Ik wilde in dit bericht meer info plaatsen, maar Bridge Online kan ik een aantal uren al niet meer openen.

De OData query time-out heb ik al eens veranderd, zoals beschreven in Vermijd time-out fout bij Power BI OData download - invantive. Het is een lange tijd goed gegaan, maar nu krijg ik telkens bij het herladen weer deze foutmelding.

De foutcode lijkt nu gewijzigd te zijn. Ik zie nu itgenboe161 als foutcode, waar ik al eerder mee kampte (Itgenboe161/ itgenboe241 - De gegevensdownload werd geannuleerd na).

Ik kom weer in Bridge Online:

met melding:

itgenboe161
De gegevensdownload werd geannuleerd na 5 minuten, 0 seconden, waarschijnlijk door de gebruiker.

De curl geeft ook een foutmelding:

curl: (35) schannel: next InitializeSecurityContext failed: CRYPT_E_REVOCATION_OFFLINE (0x80092013) - De intrekkingsfunctie kan het intrekken niet controleren omdat de intrekkingsserver offline is.

Ik hoor graag of hier al een update over is.

De oorzaak van de melding van curl zal waarschijnlijk lokaal liggen; advies is een andere PC te proberen.

Analyse itgenboe161 na 5 minuten, tweede keer 7 minuten

De HTTP 499 met itgenboe161 lijkt bij hertest te liggen bij 900,171 rijen (7 minuten, 16 seconden) en treedt ook op vanuit Power BI Desktop via de query:

select t.*
from   ExactOnlineREST.Incremental.TransactionLinesIncremental@eol t

De URL is:

/acme-exact/odata4/ExactOnlineREST.Incremental.TransactionLinesIncremental@eol

Een testomgeving is opgezet waarna het opnieuw bekeken is met meer logging via request ID 0HNBGI0ODU7QM:00000001. Hierbij bleek dat na 900.171 rijen in 4 minuten begonnen wordt aan een andere administratie met divisiecode 3077666. Hiervan worden circa 2,011 miljoen rijen opgehaald vooraleer een verzoek tot annuleren van de download ontvangen wordt volgens de software op transactie ec4646d02522b929:

De verwachte aantallen rijen per divisie zijn op basis van itgeneor778:

Divisie Aantal
3077666 2.168.201
3101321 242
3101317 3.873
3138257 278
3138285 1.497
3138305 4.114
3157850 8.176
3258681 1.261
3302180 168
3374315 872.891
3374318 6.429
3374321 1.242
Totaal 3.068.372
Totaal behalve grootste 900.171

Blijkbaar worden alle administraties behalve de allergrootste binnen 4 minuten verwerkt. De allergrootste komt echter slechts tot 2.011.000 rijen vooraleer het verzoek geannuleerd wordt om 2025-03-31T20:22:21.7981143Z, waardoor de laatste 157.201 niet opgehaald worden.

De laatste activiteit op de eerstvolgend grootste divisie 3374315 plaats vindt om 2025-03-31T20:17:18.3417795.

Het valt op dat de laatste activiteit van 3374315 5 minuten en 3 seconden eerder plaatsvindt vooraleer de grootste vroegtijdig stopt.

Het lijkt er op dat Power BI Desktop besluit dat indien er 5 minuten geen enkele rij binnengekomen is, om dan de download te annuleren. Deze annuleringsverzoek wordt door Invantive Bridge Online opgepakt en netjes omgezet in het gewenste gedrag: een afgebroken download.

Merk op dat niet elke afgebroken download hiermee samenhangt: ook een willekeurige andere download die langer dan 5 minuten liep kan afgebroken zijn omdat er geen enkele rij verstuurd werd gedurende 5 minuten.

Sterk vergelijkbare problemen zijn:

Helaas is geen enkele keer gelukt om dit probleem reproduceerbaar te krijgen. Dat is met dit probleem wel het geval.

Een vergelijkbaar probleem (maar zonder oplossing) op de Microsoft-community is:

Samenvatting: indien er 5 minuten lang geen rijen getransporteerd zijn (zoals veelal bij grote incrementele tabellen het geval is), dan zal Power BI Desktop de download afbreken.

Microsoft OData bug/beperking

Een mogelijk historische bug in de Microsoft OData-client die hiermee samenhangt is:

waarbij ReadWriteTimeout ingesteld kan worden:

so we check if the user set this value, if they did not set it then it is zero. If the user set the value then the HttpWebRequest uses that value. Otherwise it uses its default value which is 300 seconds for the ReadWriteTimeout property.

en

timeout is the number of milliseconds to wait before the request(basically the connection) timesout while readWriteTimeout is the number of milliseconds to wait before the writing/reading of a request/response timeouts.

waarbij een aanpassing gemaakt is in src/Microsoft.OData.Client/ODataRequestMessageWrapper.cs, te vinden op odata.net/src/Microsoft.OData.Client/ODataRequestMessageWrapper.cs at 01d32a4f8c892eb3f6aa4e1d6715b51dbd2196ce · ElizabethOkerio/odata.net · GitHub.

Hierin wordt sinds 2020 de volgende code mogelijk gemaakt:

            if (requestInfo.ReadWriteTimeout != 0)
            {
                requestMessage.ReadWriteTimeout = requestInfo.ReadWriteTimeout;
            }

Deze wordt aangeroepen door ODataMessageWritingHelper.cs. Er is toen geen voorziening getroffen hiervoor binnen Power BI.

In 2024 is de logica verplaatst naar een lager gelegen bibliotheek vanwege het intensievere gebruik van .net core in plaats van .net framework. Ook toen is geen voorzieningen getroffen voor het instellen van de ReadWriteTimeout op een HTTP request waardoor de standaardwaarde altijd 5 minuten blijft zoals beschreven in HttpWebRequest.ReadWriteTimeout Property (System.Net) | Microsoft Learn. Het is niet bekend of Power Query op Mac Excel die HttpClient gebruikt hier wel of geen last van heeft omdat de eigenschap vervallen is in HttpClient.

Er is ook geen ongedocumenteerde feature voor gevonden:

Samenvatting: de Microsoft OData-bibliotheek die Power BI gebruikt heeft een standaardwaarde van 5 minuten voor ReadWriteTimeout. Deze instelling kan niet veranderd worden.

Oplossingsrichtingen

Het probleem zal verder binnen Invantive besproken worden. Mogelijke oplossingsrichtingen worden hier beschreven.

Oplossingsrichting: bug report Microsoft Power BI

De ideale oplossingsrichting is het indien en laten oplossen van de beperking/bug van de OData-feed. Echter, gezien ervaringen met andere problemen op Power BI is niet de verwachting dat een dergelijke bug binnen drie jaar na melding opgelost en uitgerold zal zijn.

Oplossingsrichting: UniversalSQL Server beschikbaar binnen Invantive Cloud zelf

Een ander protocol (TDS) is in ontwikkeling (zie Topics met de tag invantive-universalsql-server). Mogelijkerwijs heeft de Power BI-driver hiervan geen foutmelding.

Workaround: download herhaaldelijk starten

In het algemeen zal een volgende laadpoging meer data uit de HTTP-caches kunnen halen. Dit verklaart waarschijnlijk ook het relatief beperkte aantal problemen die hiervoor ontstaan, evenals dat er meestal meerdere grote administraties zijn.

De volgende grove metingen zijn gedaan zonder kalibratie en zonder herhaald meten:

  • ophaalsnelheid uit result set cache is circa 12,000 boekingsregel per seconde,
  • uit incrementele cache circa 11,000 boekingsregels per seconde,
  • uit HTTP cache circa 10,000 boekingsregels per seconde,
  • vers vanuit Exact Online API-platform 1,250 boekingsregels per seconde.

Er van uit gaande dat het ophalen van de circa 2,2 miljoen boekingsregels uit de grootste administratie pas begint nadat de andere 900,000 al opgehaald zijn, zal de realistisch te verwachten maximale downloadduur 2200 seconden zijn indien alle caches leeg zijn.

Bij volledig gevulde caches is de minimale downloadduur 183 seconden.

De maximale dataset omvang convergeert bij oneindig aantal downloadpogingen naar pakweg 2,95 miljoen rijen. Dit sluit aan bij eerdere ervaringen met grotere administraties die via Invantive Cloud in plaats via Data Hub verwerkt werden.

De cijfers varieren enigszins afhankelijk van Exact Online SaaS of Exact Online Premium.

Merk op dat veel hogere aantallen mogelijk zijn indien er meerdere administraties beschikbaar zijn en blijven om vanuit te laden, zoals in grote accountancy-omgevingen.

Uitgaande van 2,2 miljoen rijen zullen tenminste 10 downloadpogingen nodig zijn om de ReadWriteTimeout van 300 seconden te omzeilen en uitgaande van de hieronder getoonde doorvoersnelheden:

Het scenario ziet er slechter uit indien de datasets van Exact Online opnieuw geladen moeten worden. Incidenteel kloppen de cijfers uit Exact Online niet en moet alles opnieuw geladen worden.

Oplossingsrichting: druppelsgewijs teruggeven

Een oplossingsrichting zou kunnen zijn om zolang het verzamelen van data actief is alvast af en toe een rij terug te geven. Dat kan door een API te gebruiken die gepagineerd is of door meerdere partities/administraties gelijktijdig uit te lezen.

Echter, specifiek de incrementele tabellen op Exact Online en Freshdesk hebben als eigenschap dat ze pas na volledige bepaling rijen terug kunnen geven. Voorheen kon dat in principe nog eerder, maar vanwege benodigde workarounds voor bugs/beperkingen in de Power Query-implementatie in Excel is dit momenteel niet eenvoudig meer realiseerbaar.

En blijkbaar komt ook de combinatie voor dat er 1 specifieke administratie tenminste 300 x 1250 rijen = 375,000 rijen groter is dan de alle andere, waardoor in de praktijk dan tenminste 1x een time-out na 5 minuten kan optreden, en vaker als de dataset groter is.

Oplossingsrichtingen zijn bijvoorbeeld:

  • de laatste 100 rijen uit een andere partitie/administratie zeer geleidelijk terug te geven per stuk of per karakter als er geen andere partities/administraties rijen teruggeven, bijvoorbeeld 1 per 240 seconden. Hierdoor blijft de verbinding in stand.
  • of eenvoudiger: proberen lege JSON terug te geven mits dat binnen de standaard valt, maar voor zover bekend momenteel voorziet de standaard daar niet in.
  • proberen bij initiële load vroegtijdig rijen terug te geven rekening houdend met de beperkingen in de Power Query-implementatie in Excel.

Oplossingsrichting: snelheidsverhoging

Door de snelheid te verhogen verschuift de limiet naar achteren:

  • Verhogen van de doorvoersnelheid vanaf de Exact Online API indien sprake is van Exact Online Premium (maximaal 10% hogere limiet).
  • Op Exact Online Premium door via skiptoken gokken van transactienummers in de private database een hogere doorvoersnelheid na te streven dan 75 calls per minuut.

Oplossingsrichting: heartbeat / ping

De ReadWriteTimeout wordt doorgezet naar de NetworkStream. Echter, er zijn geen faciliteiten om een heartbeat, ping of out-of-band bericht te sturen.

Oplossing: rijen die niet voldoen aan filter

Het filter vermijdt een aantal rijen. Het is mogelijk om “neprijen” doorlopend te retourneren die client-side door Power BI weggefilterd worden.

Oplossing: beperken overhead voor ophalen begin door gelijktijdig starten incrementele verwerking

Het verzamelen van de data voor een incrementele tabel gebeurt in sequentiële stappen. Aangezien de initiële stappen steeds langer duren door het groeiend aantal rijen die reeds verwerkt zijn, zal steeds meer tijd hieraan verloren gaan. Mogelijk is het haalbaar om delen gelijktijdig te verwerken zodat het ophalen van data bij de Exact Online API zo vlot mogelijk start en het aantal pogingen beperkt wordt. Het maximaal aantal rijen van nu 2,8 miljoen rijen voor 1 administratie binnen 5 minuten zal dan kunnen stijgen naar een significant hogere waarde na een aantal pogingen.

Oplossing: beperken overhead door optimaliseren code

Het verzamelen van de data voor een incrementele tabel gebeurt in sequentiële stappen. Aangezien de initiële stappen steeds langer duren door het groeiend aantal rijen die reeds verwerkt zijn, zal steeds meer tijd hieraan verloren gaan. Mogelijk is het haalbaar om de initiele stappen te optimaliseren qua performance. Het maximaal aantal rijen van nu 2,8 miljoen rijen voor 1 administratie binnen 5 minuten zal dan kunnen stijgen naar een significant hogere waarde na een aantal pogingen.

Workaround: uitputting vermijden

Het aantal rijen is al vroegtijdig bekend zoals zichtbaar in het stromenschema.

Eventueel kan het aantal partities dat gelijktijdig verwerkt worden van een dataset beperkt worden zodat bijvoorbeeld de kleinste dataset als langste loopt met een minimale doorvoersnelheid.

Dit is gelijkend op druppelen, maar dan doordat de gebruiker zelf de uitgaande doorvoersnelheid verlaagt bijvoorbeeld via de driverattribuut requests-max-parallel.

Workaround: front-loading / pre-loading met curl of code

Het probleem speelt enkel bij Power BI en Power Query door het overnemen van de standaardnetwerkinstellingen zonder daarvoor een configuratie-optie te bieden.

Door gebruik te maken van curl of code in een programmeertaal met de juiste instellingen kunnen de caches geladen worden. Voor optimale performance moeten de instellingen qua compressie (gzip, Brotli, geen) dusdanig zijn dat ook de result set-cache gebruikt kan worden.

De API-limieten van Exact Online Premium worden of zijn schijnbaar verlaagd: waar die voorheen 300 API-calls per minuut waren worden dat maximaal 60 API-calls tenzij men bijbetaalt.

Ook het maximaal aantal API-calls per dag wordt verlaagd voor Exact Online Premium voor hetzelfde bedrag. Ook voor Exact Online SaaS worden de API-calls verregaand verlaagd door op abonnementsniveau te gaan tellen (dus over administraties heen). Voor het gebruik van de XML API worden de limieten een factor 50 verlaagd.

Zie voor meer details:

Uit onderzoekt blijkt dat de oude limiet van 300 API-calls gehandhaafd wordt voor apps waar men reeds met een Exact Online Premium-omgeving verbinding heeft gehad. Voor nieuwe apps die geautoriseerd worden, wordt blijkbaar weer een van 60 API-calls per minuut gehanteerd, tenzij men een upgrade afneemt.

De limiet van 30.000 API-calls lijkt zowel voor recent als vroeger gekoppelde apps gehanteerd te worden.

In de volgende release van Invantive UniversalSQL zal een eventueel hogere Exact Online-minuutlimiet gebruikt worden, maar nieuwe Exact Online-gebruikers zullen hiervan geen profijt hebben tenzij ze eerder met Invantive Cloud gekoppeld hebben.

De resterende volgende oplossingsrichtingen (buiten de workarounds die een gebruiker kan maken) zijn:

  • Bug report Microsoft Power BI.
  • Druppelsgewijs teruggeven / uitsmeren in de tijd.
  • Rijen teruggeven die niet voldoen aan filter
  • Beperken overhead voor ophalen begin door gelijktijdig starten incrementele verwerking
  • Beperken overhead door optimaliseren code
  • UniversalSQL Server beschikbaar binnen Invantive Cloud zelf