Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Performance / reading all child nodes of a root node
July 31, 2015
9:01, EEST
Avatar
reinhold.kern
Member
Members
Forum Posts: 7
Member Since:
July 6, 2015
sp_UserOfflineSmall Offline

Hi,
I have a question regarding performance improvements. I have to read and persist all node values of the root node of a machine.
Currently I iterate over all nodes recursively using the ‘browse’ method of AddressSpace. I takes about 6 Minutes. Is there maybe a more efficient way how I can retrieve
all child node values?

Thanks in advance.

July 31, 2015
10:20, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

Can you post some code; it would make it much easier to analyze. What do you mean by a “machine”, a complete UA server? or some UA types/instances under a FolderType node?. In case you do try browse from the Root node of the server (Identifiers.RootFolder), there is not much that can be helped since UA address space is not designed to be browsed completely. You can do it of course, but since there are lots of nodes (i.e. types, and lots of properties in nodes anyway) it will take long. Any possiblity that you could explain why you need to do it?

In case you were happen to be building a graphical view of the address space of the server, i.e. similar to which UaExpert has; those are usually done so that whenever user expands the node in the view, the browse is done then, not by trying to cache the whole tree beforehand.

Also, as long as you use the ReferenceDescriptions returned by the AddressSpace.browse it is somewhat best you can do. IF you do call AddressSpace.getNode, then the node is cached as UaNode implementation, i.e. it does fetch the attributes, references and Properties of that node. This can take time if done for a large amount of nodes. Also the cache has limited size and duration, defaults are 5000 nodes and 1 second. If your code tries to do something with more than 5000 nodes at the same time or longer than 1 second, it might trigger fetching the data again when you call AddressSpace.getNode with the same NodeId. For example our graphical client https://prosysopc.com/products/opc-ua-client/ only uses the getNode for the selected node in the address space view and not for every node seen in the view.

– Bjarne

July 31, 2015
11:48, EEST
Avatar
reinhold.kern
Member
Members
Forum Posts: 7
Member Since:
July 6, 2015
sp_UserOfflineSmall Offline

Hi Bjarne,

yes, with ‘machine’ I meant the UA server running on a injection moulding machine. I browse not from the main root node (Identifiers.RootFolder) but 2 hierarchy levels deeper. For example: Root->Objects->Arburg. I have to log the complete data of this node (and all its children) for each single peace that is produced on the machine. This is done for optimizing and analyzing the production process. Under this node there are about 22 000 child nodes in sum. Here is my code:

public ArburgHistory getHistoryForNode(ArburgNode node) {
//get arburg node
UaNode startNode = addressSpace.getNode(new NodeId(2, 1111);

}

//get nodes recursive
private List<ArburgHistoryEntry> browseTree(AddressSpace addressSpace, UaNode node, ArburgHistory history) {

List<ArburgHistoryEntry> historyList = new ArrayList<ArburgHistoryEntry>();

try {
List<ReferenceDescription> browseList = addressSpace.browse(node.getNodeId());
Iterator<ReferenceDescription> browseListIt = browseList.iterator();

List<ArburgHistoryEntry> historyTmp = new ArrayList<ArburgHistoryEntry>();
while (browseListIt.hasNext()) {
ReferenceDescription refDescr = (ReferenceDescription) browseListIt.next();
historyTmp.addAll(browseTree(addressSpace, addressSpace.getNode(refDescr.getNodeId()), history));
}

ArburgHistoryEntry historyEntry = getHistoryEntry(node); //map UaNode to entity objetct
historyEntry.setArburgHistory(history);

for (ArburgHistoryEntry arburgHistoryEntry : historyTmp) {
if (arburgHistoryEntry.getParentHistoryEntry() == null) {
arburgHistoryEntry.setParentHistoryEntry(historyEntry);
historyEntry.setArburgHistory(history);
}
historyList.add(arburgHistoryEntry);
}

historyList.add(historyEntry);

} catch (ServiceException | StatusException | AddressSpaceException e) {
String msg = MessageFormat.format("Browse list empty or not readable at node: ”{0}”", node.getBrowseName());
log.error(msg, e);
}

return historyList;
}

July 31, 2015
13:55, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Ok, seems to be interesting use case. I see 2 options.

1)
You could just use the ReferenceDescriptions without fetching the node with getNode and use UaClient.read methods to read the Attributes you need. ReferenceDescription contains the NodeId/BrowseName/DisplayName/NodeClass attributes + type definition. In UA you can use the Read service for multiple attributes for multiple nodes in one call so it should be more efficient. For attributes other than value, you might need to do the ReadValueId for the calls in UaClient, use null for IndexRange and DataEncoding. Also for this large amount, you might want to limit the the number of items you read in the same request (maybe try with reading attributes for one node at a time and see if it is fast enough). The server might set operation limits in Server/ServerCapabilities/OperationLimits but it is optional (as is the node too), if they are defined the UaClient will split the read, but it may also be that server has set no limits (or is not able to take 22000 x number of attributes you need reads in one request).

2)
Or you could just get the top level node with .getNode, and use UaNode.getReferences(Identifiers.HierarchicalReferences, false) to go forward and not use browse. Note that I have not used this method to traverse the entire address space (or a huge part of it anyway), so I would recommened the first option. You could also try to set the cache larger and more permanent, AddressSpace.getCache and .setMaxQueueLength and setNodeMaxAgeInMillis. You could also clear that after saving with .clear.

If you do both browse and .getNode for each node, it is essentially the same work done twice, since .getNode reads all references/attributes and property nodes when you call .getNode. The references are stored in a way that when you do call UaReference.getTargetNode it fetches it from the AddressSpace with .getNode automatically.

– Bjarne

(There is a third option which might be useful in cases like this in the future. The specification defines a service Query, which might help to do data searches like this (for instances of types). But to my knowledge there is not a server yet which would support this.)

August 3, 2015
7:08, EEST
Avatar
reinhold.kern
Member
Members
Forum Posts: 7
Member Since:
July 6, 2015
sp_UserOfflineSmall Offline

Hi Bjarne,

thanks for your reply and you suggestions.
Not using browse has brought me already 30 seconds 🙂

-Reinold

August 10, 2015
11:11, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Great!

You could also try the 1) option. It should be faster (not sure how much, but some), but does require a bit more work to implement.

– Bjarne

March 17, 2017
8:01, EET
Avatar
kumarm_naveen
New Member
Members
Forum Posts: 1
Member Since:
March 17, 2017
sp_UserOfflineSmall Offline

Hi All,

I am in same situation as “reinhold.kern”.

I need to read all child nodes in single request. Is there any way to do this?

@reinhold.kern if you already achieved solution, could you please share?

thanks
Naveen

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 518

Currently Online:
14 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

hbrackel: 135

pramanj: 86

Francesco Zambon: 81

rocket science: 77

Ibrahim: 76

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

fred: 41

Member Stats:

Guest Posters: 0

Members: 682

Moderators: 16

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1468

Posts: 6262

Newest Members:

joliecheney96, digitechroshni, LouieWreve, Kickbiche, karrimacvitie5, graciela2073, sagarchau, elviralangwell4, Donnavek

Moderators: Jouni Aro: 1010, Otso Palonen: 32, Tuomas Hiltunen: 5, Pyry: 1, Petri: 0, Bjarne Boström: 983, Heikki Tahvanainen: 402, Jukka Asikainen: 1, moldzh08: 0, Jimmy Ni: 26, Teppo Uimonen: 21, Markus Johansson: 42, Niklas Nurminen: 0, Matti Siponen: 322, Lusetti: 0, Ari-Pekka Soikkeli: 5

Administrators: admin: 1