we may encounter a concurrent issue. ElasticSearch has mechanish to prevent the concurrent update.
here is the sample code to get information from bundle and book information for response.
app.put('/api/bundle/:id/book/:pgid', async(req, res)=>{
        const bundleUrl =`${url}/${req.params.id}`;
        const bookUrl=`http://${es.host}:${es.port}/${es.books_index}/book/${req.params.pgid}`;
        try{
            const [bundleRes, bookRes]=await Promise.all([
                rp({url:bundleUrl, json:true}),
                rp({url:bookUrl, json:true})
            ]);
            console.log(bundleRes);
            const {_source: bundle, _version: version}=bundleRes;
            const {_source: book}=bookRes;
            console.log("if_seq_no:",if_seq_no);
            console.log("if_primary_term", if_primary_term);
            const idx=bundle.books.findIndex(book=>book.id===req.params.pgid);
            if(idx === -1){
                bundle.books.push({
                    id: req.params.pgid,
                    title: book.title
                });
            }
            const esResBody=await rp.put({
                url:bundleUrl,
                qs:{
                    version: version, 
                    version_type: 'external',
                },
                body:bundle,
                json:true
            });
            res.status(200).json(esResBody);
        }catch(esResErr){
            res.status(esResErr.status ||502).json(esResErr.error);
        }
    })
initially i try to use the version number to resolve the concurrent issue. the error is thrown immediately after the request is made.
{
"error": {
"root_cause": [
{
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
}
],
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
},
"status": 400
}
based on the suggestion from the error message. i need to make couple of change, in order to fix the issue.
first we need to load the _seq_no and _primary_term from bundle response body.
 const {_source: bundle, _version: version,  
_seq_no: if_seq_no,
_primary_term:
if_primary_term }=bundleRes;
_seq_no: if_seq_no,
_primary_term:
if_primary_term }=bundleRes;
 const {_source: book}=bookRes;
second, add if_seq_no and if_primary_term to the query string array
const esResBody=await rp.put({
                url:bundleUrl,
                qs:{
                    if_seq_no: if_seq_no,
                    if_primary_term: if_primary_term
                },
                body:bundle,
                json:true
            });
Now the concurrent issue is gone. the title update is done,
danhuideng@DESKTOP-EE785O3:/mnt/c/node/b4$ curl -s localhost:60702/api/bundle/$BUNDLE_ID |jq '._source'
{
"name": "far",
"books": [
{
"id": "pg132",
"title": "The Art of War"
}
]
}
No comments:
Post a Comment