A new approach to the diagnosis of mental illness
Our client's vision was that mental health should be available to everyone. The current diagnostic approach with short doctor-patient interactions makes it difficult to detect a disease in the early stage. Many scientists see the future of mental health diagnostic in combining psychometry with information technologies. This involves changing the current approach to diagnosis and requires tools that can effectively track mental health over long periods.
Our client, in this case, was a startup based at Basel University. They were striving to create a new way of diagnostics and prevention of mental diseases. This approach was to combine psychometrics and gamification. While a patient plays computer games, the system receives and processes their data, and a doctor can make a quality diagnosis of the mental health of this patient. Specifically, the product targets to diagnose ADHD and Alzheimer's disease.
The product requires many areas of expertise and advanced technological solutions to solve such a problem. At the beginning of the collaboration, some unresolved technical issues significantly slowed down the development of the product. We had to help solve these problems.
The first input was: “We need to optimize some applications on Scala, evaluate their effectiveness and choose the correct tools and technics to scale these applications.” In other words, we need to work with a startup's early stage product with Scala back-end and which needs to be scaled up. Scala choice as the main programming language is not ordinary for early MVPs. The Scala language is rarely used for startups at this stage. Moreover, we were surprised that our client has already come to a scale problem. Usually, the infrastructure of the early-stage products is small. In our practice, the cost of the infrastructure is usually no more than 5% of the average monthly expenses.
We got the answers to these questions already on the first call. The previous team had chosen the technologies based on their skills and vision for the product. The choice became quite clear to us because good developers prefer professional tools. From this choice, the product can significantly benefit in the future when product constraints become difficult to fulfill.
At the same time, our client guessed that this choice has a downside: complicated instruments could slow down the tempo of development. There was an objective reason for Advancience's concerns about product scalability. They worried that technical questions could block checking science and business ideas. It's quite a reasonable statement of a question, cause especially in the early stage, developers have to make conflicting decisions, which could decrease the productivity of the development process.
Another important issue was the product security. For a startup in the healthcare industry, which collects and analyzes people's data, it's critical to protect user data. These mistakes cannot be excused in this market. As a result, we formed a common vision with the client about the goals of cooperation:
We've created a repeatable application setup process for local development and production deployment. So each developer could quickly run the application locally or deploy it to the university's servers.
Creating a CI/CD pipeline. Building a plan for vertical and horizontal scaling of the product.
Basic application performance monitoring.
Security audit of the product and building a plan of decreasing threats.
As we got access to the product repositories and deployment, we were assured that we could be effective in this collaboration. The product's design was clear, the entire code base was on Gitlab, and we have a good understanding of Gitlab CI/CD.
The first result of our work was a product assessment report. We analyzed the code base, identified the main difficulties in the current development process, and described the optimal approach to solve them. We suggested a concrete set of actions to make the product transferable. It was impossible to take the following steps without it. Also, here we described the product's vertical and horizontal scaling.
The main goal is to increase IOPS, CPU and RAM power, and disk space on a single server. This approach is productive in the early stages of product development when it does not yet require cloud infrastructure, and deployment is done manually for cost-effectiveness reasons.
We introduced the client to cost-effective solutions, where you can increase the server capacities, such as Hetzner Cloud.
Moreover, we described the scenario of moving applications from one server to another.
- All dependencies for each application are supported as installation instructions for each application in the file readme.md
- We maintain critical performance constraints and a way to test them for each application. Thus we can estimate what server we need to run the application with the required performance.
- We moved all environment-dependent parameters to the environment variables and allowed passing them with .env files on each application. Also showed how to document these parameters.
The main goal is to deploy multiple copies of the same application, working identically and simultaneously. This is necessary to improve system fault tolerance and increase system throughput.
Some microservices had a bottleneck for CPU-bound operations, and the database queries took relatively little time. In this case, it was efficient to run several application instances simultaneously.
- Deployment and configuration of the application is similar to vertical scaling.
- We have described the threats of such distributed systems, such as giving one task to two workers.
- The next step is manual scaling or autoscaling. In the first case, you can deploy a new application instance in a few clicks in the administrative panels. In the second case, specialized software deploys it automatically when the load increases. We have described to the client how to prepare for these steps.
After the client solved the product portability problems, we moved to the next questions. We needed to improve development speed and development experience. The task was to overcome the barrier of entry of unfamiliar technologies and learn how to efficiently and quickly solve working problems. In this case, the best way to explain how to deal with the technology was to show some working examples. We solved the following issues:
At this stage, we had already solved the client's main problem: transferring and scaling applications became straightforward and convenient. We eliminated the threat of spending a lot of time or money on this. The following tasks were:
A centralized logging solution using ELK. It was timely, as the number of microservices was already substantial, and the amount of data necessary for tracking had also grown. As a nice bonus, we could now log the data into ELK for further analysis to test some hypotheses.
Automatic deployment of the application via git push to a branch. Technically, the product was already ready for this task, significantly reducing the developers' time.
The system of monitoring and notification of technical and product metrics using Grafana and Prometheus.
In the end, our client could focus on his primary tasks: developing the business model and the research. At this time, we continued to consult our client on emerging issues with the introduced technologies. We also helped set up an on-prem Sentry for logging technical errors; suggested a structure for events logging; set up pgHero, and suggested how to use it.
In this collaboration, we helped Advancience solve resource-intensive problems most optimally. We ensured once again that even when advising a client on technical questions, it is crucial to understand their business model. Without understanding it, we would be constantly bogged down in insignificant details, not understanding the client's real problems.