a month ago
I'm investigating a potential race condition in an SAP CAP service where req.user or cds.context might be overwritten by another request during an internal POST call.
Here is a simplified version of the code:
const cds = require('@sap/cds'); const LOG = cds.log(); module.exports = class TesteRace extends cds.ApplicationService { init() { this.on('TesteC', async (req) => { try { const srv = await cds.connect.to('TesteRace'); LOG.info(`Executing TesteC - User from req.user: ${req.user?.attr?.email || req?.user?.id || 'empty'}`); LOG.info(`Executing TesteC - User from cds.context: ${cds.context.user.attr.email || cds.context?.user?.id || 'empty'}`); return await srv.post(this.entities.TesteA).entries([{ nome: req?.data?.nome || Math.random() * 1000 }]); } catch (error) { req.error(error); } }); this.before('CREATE', this.entities.TesteA, async (req) => { req.data.nome = `${req.user?.attr?.email || cds.context?.user?.id || cds.context?.user?.attr?.email} ${Math.random() * 1000}`; LOG.info(`Before CREATE TesteA - User from req.user: ${req.user.attr.email || 'empty'}`); LOG.info(`Before CREATE TesteA - User from cds.context: ${cds.context?.user?.id || cds.context?.user?.attr?.email || 'empty'}`); }); this.before('CREATE', this.entities.TesteB, async (req) => { req.data.nome = `${req.user?.attr?.email || cds.context?.user?.id || cds.context?.user?.attr?.email} ${Math.random() * 1000}`; LOG.info(`Before CREATE TesteB - User from req.user: ${req.user.attr.email || 'empty'}`); LOG.info(`Before CREATE TesteB - User from cds.context: ${cds.context?.user?.id || cds.context?.user?.attr?.email || 'empty'}`); }); return super.init(); } }
Has anyone experienced a similar issue? Could cds.context unexpectedly be shared between requests? Any insights would be greatly appreciated! 🚀
Request clarification before answering.
Hi, are you okay ?
The test is that two users are making two different posts at the same time, but in different entities.
However, the entity of the first user is picking up the email of the second user because they are running simultaneously.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Update: Found the Root Cause – It Was cds.connect.to Causing the Race Condition After further investigation, I found the root cause of the race condition in my SAP CAP service. The issue was due to the use of await cds.connect.to to call an internal service within the same CAP application.
cds.on('served', async ()=> {
const db = await cds.connect.to('db') // DANGER: will cause race condition !!!
db.on('before', (req) => console.log(req.event, req.path))
})
Documentation: https://cap.cloud.sap/docs/get-started/troubleshooting#don-t
Hello,
we replaced cds.connect.to with cds.services, and the race condition behavior stopped.
Hello @fabi2295 ,
Please verify if SAP CAP's locking mechanisms can help prevent req.user and cds.context from being overwritten by concurrent requests.
Please refer: https://cap.cloud.sap/docs/node.js/cds-ql#forupdate
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
87 | |
11 | |
9 | |
8 | |
6 | |
6 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.