# TagProvider.getTagConfigsAsync vs .browse

**URL:** <https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976>\
**Category:** Module Development\
**Created:** [September 13, 2024, 9:40pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976 "2024-09-13T21:40:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrew\_Cunningham](https://avatars.discourse-cdn.com/v4/letter/a/9f8e36/32.png) [@Andrew\_Cunningham](https://forum.inductiveautomation.com/u/Andrew_Cunningham)\
**Post date:** [September 13, 2024, 9:40pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/1 "2024-09-13T21:40:41Z")

</div>

Hi all, long time no type.

TL;DR: Does ignition hold a lock while resolving `tagProvider.getTagConfigsAsync("[$provider.name]", recursive=true, local=false)` ?

I'm revisiting some code which we use in a plugin to analyze the entire gateway configuration tag space, running provider-by-provider.

We've seen experientially that while I'm running a scan of all tags, it seems to put a lot of load on the gateway of some sort, because the rest of the system runs into timeouts reading & writing to tags. I theorize that this is because the gateway is holding a sqlite table lock (or lots of row locks or or or) while doing these resolutions, so when we get to a vary large deep provider, it spends a _long_ time recursively flattening the whole object, and that causes problems elsewhere.  
The whole process takes about 180s to complete, so the performance gaps while this is happening are Not Great!

Standard metrics (thread pools I can monitor, cpu, ram, jvm gc etc) all seem fine.

Using that theory ("recursive=true holds a resource for too long, split the work up!"), I started exploring using the `browseAsync` api instead, but for my purposes I think that it's not suitable.  
We use custom attributes on tags pretty heavily, and they don't come through the browse API at all. And I don't think that there's a path towards using `getTagConfigsAsync` _without_ `recursive=true` because -- as far as I can tell -- there's no way to get tags _under_ a path with it, just tags _at_ a path.

Ignition 8.1.35 for API purposes, but this is important, if I need to upgrade I'll make it happen 😃

Any advice appreciated!

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [September 13, 2024, 10:45pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/2 "2024-09-13T22:45:16Z")

</div>

> [@Andrew\_Cunningham](#):
>
> TL;DR: Does ignition hold a lock while resolving `tagProvider.getTagConfigsAsync("[$provider.name]", recursive=true, local=false)` ?

Not a lock exactly, but there is a single-threaded Executor that operations against a tag provider are executed on, including this one, and calling this with `recursive=true` at against the root of a large tag provider will block other operations until it completes.

Maybe you'll have to use some combination of `browseAsync` and `getTagConfigsAsync`?

---

<div class="post-metadata">

**Author:** ![Andrew\_Cunningham](https://avatars.discourse-cdn.com/v4/letter/a/9f8e36/32.png) [@Andrew\_Cunningham](https://forum.inductiveautomation.com/u/Andrew_Cunningham)\
**Post date:** [September 16, 2024, 1:29pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/3 "2024-09-16T13:29:33Z")

</div>

Thank you, that makes sense, I'll report back.

---

<div class="post-metadata">

**Author:** ![Andrew\_Cunningham](https://avatars.discourse-cdn.com/v4/letter/a/9f8e36/32.png) [@Andrew\_Cunningham](https://forum.inductiveautomation.com/u/Andrew_Cunningham)\
**Post date:** [September 18, 2024, 5:14pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/4 "2024-09-18T17:14:34Z")

</div>

Thanks for your help @Kevin.Herron ! I can confirm that this works (switching back and forth between the `browse` api to discover children and the `tagConfig` API to fetch config at a point).

I see something unusual though.

Within the designer, when I use UDT I _do_ see properties set on the template nested under the instance:

![Screenshot 2024-09-18 at 13.00.22](https://us1.discourse-cdn.com/inductiveautomation/original/3X/d/6/d64caf9a6ed8512796650882b690a03818773c1f.png)  
(the instance of the UDT)  
 ![Screenshot 2024-09-18 at 13.02.24](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/1/f10505d26e81176c354724e3949f33c190c06898.png)  
(the definition of the UDT together with its template)

However, when I enumerate the properties of the same element with `getTagConfigAsync(path/to/instance, recursive=true, localOnly=false)` I don't see the inherited value show up, and I would have thought I would! Is there something I should be doing differently? The javadoc are pretty unclear about this unfortunately, so I appreciate your help!

The definition of the template from `_types_` getTagConfigAsync is:

```python
{
  "name": "Scannerish",
  "parameters": {
    "prefix": {
      "dataType": "String"
    }
  },
  "tagType": "UdtType",
  "tags": [
    {
      "sourceTagPath": {
        "bindType": "parameter",
        "binding": "{prefix}/{InstanceName}"
      },
      "valueSource": "reference",
      "dataType": "String",
      "name": "data",
      "AutoSub": true,
      "tagType": "AtomicTag"
    },
    {
      "AutoMqtt": {
        "bindType": "parameter",
        "binding": "none:fakeMqtt/{InstanceName}"
      },
      "valueSource": "memory",
      "AutoSrwx": 7,
      "name": "dirproxy",
      "tagType": "AtomicTag"
    }
  ]
}

```

(pay attention to those AutoSub and AutoMqtt, that's what I want to see again in the future...)

while the `getTagConfigurationAsync(path, recursive=true, localOnly=false /* or true, doesn't matter*/)` is:

```python
{
  "name": "event1",
  "typeId": "Scannerish",
  "parameters": {
    "prefix": {
      "dataType": "String",
      "value": "Realish"
    }
  },
  "tagType": "UdtInstance",
  "tags": [
    {
      "name": "data",
      "tagType": "AtomicTag"
    },
    {
      "name": "dirproxy",
      "tagType": "AtomicTag"
    }
  ]
}

```

My suspicion is that I don't understand `localPropsOnly`, because if I pick a tag I expect to inherit a property from the template and attempt to getTagConfigAsync that tag's path (like: `dirproxy` & expect to see `AutoMqtt` in the above example), I _still_ don't see the expanded property set I expect in the result.

I'm attempting to probe for the custom properties on the returned model with `TagConfigModel.get(myPropertyName)`, and falling back to this json print for debugging.  
I _think_ the `get` is failing to find the value -- but I am not sure, which is why I am debugging.  
But it might be and my bug is somewhere else, or maybe I'm misunderstanding something and should be evaluating these differently somehow?  
Maybe I should use different tag paths when expanding UDTs? Or a different definition of the properties (they're `BasicProperty`s) or something?

anyway, please let me know and thank you!

---

<div class="post-metadata">

**Author:** ![Andrew\_Cunningham](https://avatars.discourse-cdn.com/v4/letter/a/9f8e36/32.png) [@Andrew\_Cunningham](https://forum.inductiveautomation.com/u/Andrew_Cunningham)\
**Post date:** [September 18, 2024, 7:22pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/5 "2024-09-18T19:22:23Z")

</div>

Update:  
The parameters I want are present in the `TagConfigModel.inheritedConfiguration` (and afaict more reusably, they're also flattened into the `TagConfigModel.values` so I don't even have to check local inherited separately, which is nice)!  
However, I'm not done yet.

In my example both versions used bindings. And the expressions that use bindings seem to be returned raw (which is useful, but not perfect).

Is there an API to get the evaluated version back? I begin to suspect (per [Tag Paths | Ignition User Manual](https://www.docs.inductiveautomation.com/docs/8.1/platform/tags/tag-paths) ) that I should explore with the `browse` API, fetch property sets with the `tagModel` API to see if the fields I want are present, and then evaluate the actual properties with the `read` API (using the same path as the parent but with a `.someProperty` at the end). Yeah?

(actually, looks like the tagModel API is pretty optional if I'm going to end up looking for the values I know I want anyway with read(some/path.someProperty) since I know which properties I care about)

---

<div class="post-metadata">

**Author:** ![Andrew\_Cunningham](https://avatars.discourse-cdn.com/v4/letter/a/9f8e36/32.png) [@Andrew\_Cunningham](https://forum.inductiveautomation.com/u/Andrew_Cunningham)\
**Post date:** [September 18, 2024, 8:56pm UTC](https://forum.inductiveautomation.com/t/tagprovider-gettagconfigsasync-vs-browse/95976/6 "2024-09-18T20:56:39Z")

</div>

Utter success!

So: for my purposes, the TagModel api is good but not great; async reads to the properties I knew I wanted anyway were a lot more straightforward. Thanks for your help; happy to suggest or donate docs if that would be useful!
