# How many tags can tag.readBlocking handling?

**URL:** <https://forum.inductiveautomation.com/t/how-many-tags-can-tag-readblocking-handling/58005>\
**Category:** Ignition\
**Tags:** ignition80\
**Created:** [April 4, 2022, 3:31pm UTC](https://forum.inductiveautomation.com/t/how-many-tags-can-tag-readblocking-handling/58005 "2022-04-04T15:31:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![huyao](https://avatars.discourse-cdn.com/v4/letter/h/aeb1de/32.png) [@huyao](https://forum.inductiveautomation.com/u/huyao)\
**Post date:** [April 4, 2022, 3:31pm UTC](https://forum.inductiveautomation.com/t/how-many-tags-can-tag-readblocking-handling/58005/1 "2022-04-04T15:31:42Z")

</div>

I got a problem when this function take 100 tags as a list with 2500 ms time out setting.  
Everytime I read some rows in the PLC. Each row gets 5 tags, the last tag is an incremental log Id.  
A trigger tag was used to log those row into mysql database by tag change event.  
However after a few successfull log, some rows with all 0 value will ocurr in database.  
The log Id indicated those values was read as 0 in the tag change script.  
So does anyone get the same problem?  
I added a log to calculate the time cost, the whole script took 120~140 ms in total, so the timeout shall not be a problem

---

<div class="post-metadata">

**Author:** ![huyao](https://avatars.discourse-cdn.com/v4/letter/h/aeb1de/32.png) [@huyao](https://forum.inductiveautomation.com/u/huyao)\
**Post date:** [April 4, 2022, 3:47pm UTC](https://forum.inductiveautomation.com/t/how-many-tags-can-tag-readblocking-handling/58005/2 "2022-04-04T15:47:32Z")

</div>

My script as bellowing, PLC was rockwell control logix.

```auto
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
    if not initialChange:
        logstart = system.date.now()
        logger = system.util.getLogger("Heartbeat event trigger")
        oktoreadpath = '[default]_tmp/_HeartBeat_event_monitoring/ReadAreaOk2Read'
        ReadLengthpath = '[default]_tmp/_HeartBeat_event_monitoring/ReadLength'
        dbresultpath = '[default]_tmp/_HeartBeat_event_monitoring/DBResult'
        paths = [oktoreadpath,ReadLengthpath]
        [oktosend , readlength] = system.tag.readBlocking(paths)
        readlength = readlength.value
        if oktosend.value == 1 and readlength >0:
            eventpaths =[]
            for x in range(readlength):
                equipID = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_'+str(x)+'_/Integer00'
                valueC = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_'+str(x)+'_/Integer01'
                valueP = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_'+str(x)+'_/Integer02'
                logId = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_'+str(x)+'_/Integer03'
                tsC = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_'+str(x)+'_/TimeInBuffer'
                eventpaths.extend([equipID,valueC,valueP,logId,tsC])
            taglist = system.tag.readBlocking(eventpaths)
            querystring = "insert into heartbeat_event (equipid,heartbeatc,heartbeatp,tsc,createdate,logid) values "
            valuestring = ""
            eventlist =[]
            y = 0
            for tag in taglist:
                if y%5==0:
                    equipid = tag.value
                elif y%5==1:
                    valuec = tag.value
                elif y%5==2:
                    valuep = tag.value
                elif y%5==3:
                    logid = tag.value
                else:
                    tsc = system.date.addMillis(currentValue.timestamp,tag.value*(-1))
                    valuestring = valuestring+" ("+str(equipid)+","+str(valuec)+","+str(valuep)+",'"+str(system.date.format(tsc))+"','"+str(system.date.format(currentValue.timestamp))+"',"+str(logid)+"),"
                    event = [equipid,valuec,valuep,logid,tsc]
                    eventlist.append(event)
                y = y+1
            querystring = querystring+valuestring[:-1]+';'
            n = system.db.runUpdateQuery(querystring,_dataBase)
            logstop = system.date.now()
            logger.info("heart beat trigger end successed take %s ms" % str(system.date.millisBetween(logstart,logstop)))   

```

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [April 4, 2022, 7:45pm UTC](https://forum.inductiveautomation.com/t/how-many-tags-can-tag-readblocking-handling/58005/3 "2022-04-04T19:45:37Z")

</div>

First, this appears to be in a tag change event. You should avoid long running scripts in tag change events. I would recommend that you refactor this to be used with a Gateway Tag Change Event.

This is due to the way that Tag Change Events work. You can read more on that here:

> [@Scripting architecture choices](https://forum.inductiveautomation.com/t/scripting-architecture-choices/56976):
>
> I am looking at cleaning up my first Ignition project that was released to the wild (Under v8.1). While it works I didn’t make the best design choices which has resulted in a complicated (IE ugly) maintenance process. The application itself is basically a data logging system that monitors multiple machines (each defined by an instance of a single UDT) and writes values to a DB on both value changed and timed events. It also has no display screens of any sort. The current architecture has 3 v…

Second, you should be using `system.runPrepUpdate()`

```python
from itertools import chain
if not initialChange:
    logstart = system.date.now()
    logger = system.util.getLogger("Heartbeat event trigger")
    oktoreadpath = '[default]_tmp/_HeartBeat_event_monitoring/ReadAreaOk2Read'
    ReadLengthpath = '[default]_tmp/_HeartBeat_event_monitoring/ReadLength'
    dbresultpath = '[default]_tmp/_HeartBeat_event_monitoring/DBResult'
    paths = [oktoreadpath,ReadLengthpath]
    [oktosend , readlength] = system.tag.readBlocking(paths)
    readlength = readlength.value
    if oktosend.value == 1 and readlength >0:
        parentPath = '[default]_tmp/_HeartBeat_event_monitoring/_HeartBeat_event_read/_DPP_Read_HBEvent_{}_/'
        eventpaths = [pPath + name for pPath in [parentPath.format(e) for e in range(readlength)] for name in ['Integer00','Integer01','Integer02','Integer03','TimeInBuffer']]
        taglist = system.tag.readBlocking(eventpaths)
        querystring = "INSERT INTO heartbeat_event (equipid,heartbeatc,heartbeatp,tsc,createdate,logid) values "
        querystring += ','.join(['(?,?,?,?,?,?)'] * (readlength / 5))
        querystring += ';'
        def step(xs):
            start = 0
            step = 5
            for x in xs:
                if start > (len(xs)-step):
                    break
                yield (start, xs[start])
                start += step

        eventlist = list(chain.from_iterable([[taglist[y].value,taglist[y+1].value,taglist[y+2].value,system.date.addMillis(currentValue.timestamp,taglist[y+4].value*(-1),currentValue.timestamp, taglist[y+3].value] for y,tag in step(taglist)]))
    system.db.runPrepUpdate(querystring,eventlist,_dataBase)
    logstop = system.date.now()
    logger.info("heart beat trigger end successed take {}ms".format(system.date.millisBetween(logstart,logstop))
```
