SORMAS-Foundation / SORMAS-Project

SORMAS (Surveillance, Outbreak Response Management and Analysis System) is an early warning and management system to fight the spread of infectious diseases.
https://sormas.org
GNU General Public License v3.0
291 stars 140 forks source link

Improve the performance of the REST-API #7905

Open marko-arn opened 2 years ago

marko-arn commented 2 years ago

Feature Description

The Rest API was designed to access data from the App on mobile phones/tablets.

Currently, the REST API is used in Germany to upload a large amount of cases/contacts to Sormas, as otherwise case processing is not possible. External software extensions to Sormas (Climedo, CISS) are used for this purpose.

Unfortunately, we have noticed that the performance of the REST API is not designed for this use. Sometimes the applications do not receive a response and therefore load the cases/contacts multiple times into Sormas. This is due to the privacy-friendly design of the applications themselves not storing any data.

Last week, a survey of German public health departments took place. It came out that out of 95 participating health departments, more than half (58) use external software to record contacts and/or cases.

According to Netzlink, this is something that needs to be given priority and adjusted in the development of Sormas, as the errors occur even on servers that have already been allocated more resources.

JonasCir commented 2 years ago

@Marko-ilmkreis I think the rest of your issue is missing? :)

marko-arn commented 2 years ago

@JonasCir The last, not completed, sentence was a error by me :-) is fixed.

JonasCir commented 2 years ago

Agreed, I witnessed slow performance of the API myself a couple of times while running tasks locally.

I will not make a promise that I cannot keep, nevertheless #7813 might be a candidate which could lead to a better overall application performance. It is not a silver bullet, but it seems like a good start :)

While working on it, however, I noticed a couple of issues:

  1. Performance testing is hard
  2. We need to improve our developer tooling around this topic (minimum #7835) such that we have direct feedback for single changes
  3. In general, we need to base our development here on real measuring and data:
    1. We need more performance metrics/insights from real deployments. Recently, Netzlink included Glowroot, but we need to find a way to make the insights available to the devs (@fhauptmann)
    2. I'm currently lacking insights into questions like: What endpoints are used frequently? Which of them are especially slow? What is the workload use there? etc. Only with this questions being answered, we will be able to work systematic on this topic. Something like Grafana Tempo or similar would be awesome, but I guess it would require some support in SORMAS. Again @fhauptmann likely can provide some insights here.
cisoLKT commented 2 years ago

Queries returning larger datasets via the REST-API often return error code 503 (Timeout - Invoke-RestMethod : The remote server has returned an error: (503) Server unavailable.) and occasionally error code 500 (Server error - Invoke-RestMethod : The remote server has returned an error: (500) Internal server error.).

Queries of single records via the UUID are successful, but as soon as a larger count of such queries is made (a pause of 2.5 seconds between each query improved the success rate of these queries...) we get a 503 again after some time.

The behavior of the REST API has deteriorated with an increasing number of cases recorded in SORMAS.

We are a German public health departments. Retrieving the data via the Rest API is mandatory since the cases have to be input manually into the local police department's system for quarantine orders (rescuetrack) otherwise (which is not feasible).

Below is an example snippet from our PowerShell script that retrieves all tasks from the last 48 hours and periodically times out. Please let us know if more information is required or if we can help with testing.

$user = 'RESCUETRACK_REST'
$pass = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

$pair = "$($user):$($pass)"

$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))

$basicAuthValue = "Basic $encodedCreds"

$Headers = @{
    Authorization = $basicAuthValue
    "Content-Type" = "application/json"
    "charset"="UTF-8"
}

# makes a HTTP-GET-Request to the specified API-Endoint $request
function makeWebRequest($request) {
    return Invoke-RestMethod -Uri "https://[SORMAS]/sormas-rest/$request" -Headers $Headers
}

# calculates unixdate x days before / after today
function calculateunixdate($daysfromnow) {
    $date1 = Get-Date -Date "01/01/1970"
    $date2 = (Get-Date).AddHours(($daysfromnow))
    $since = (New-TimeSpan -Start $date1 -End $date2).TotalSeconds
    $since =  [Math]::Floor($since) * 1000
    return $since
}

$tasksSince = calculateunixdate(-48)
Write-Host "get all tasks since 48 huors" -ForegroundColor Yellow
$Alltasks = makeWebRequest("tasks/all/$tasksSince")
JonasCir commented 2 years ago

@syntakker could you follow up on this?