Trabajo con infotables
Las infotables se almacenan en la memoria como un único objeto en la caché. Por este motivo, en ThingWorx 8.5 y versiones posteriores, la manipulación directa de infotables no se soporta porque puede dar lugar a comportamientos inesperados y problemas de rendimiento. Cuando se recupera una propiedad de la infotable de una cosa, se crea un objeto Proxy que se vuelve a comunicar con el objeto original. Los cambios directos solo se producirán en la copia local, pero las llamadas a la función actualizarán el objeto original. Si se necesita un clon completo del objeto para que no se transfieran cambios mediante Proxy hasta que todos los datos se hayan actualizado, se debe utilizar la opción de clon del recurso. En los siguientes ejemplos para infotables de una sola fila, se utiliza un objeto de empaquetador, pero para infotables de varias filas, se utiliza la opción de clon completo, ya que no se quiere actualizar cada cambio de fila.
Lo siguiente crea un objeto Proxy local (las llamadas de método actualizarán el objeto original y se guardarán en la caché):
Things["data1"] busca una cosa "datos1" por su nombre.
Things["data1"].info la propiedad de infotable "info" de la cosa "datos1"
var myinfo = Things["data1"].info
A continuación, se crea un clon completo sin cambios que se vuelve a transferir mediante Proxy al objeto original:
var myinfo = Resources["InfoTableFunctions"].Clone({ t1: Things["data1"].info });
Los datos de propiedad de ThingWorx 8.5 y versiones posteriores se tratan de forma diferente que en versiones anteriores. Ahora, todos los datos se almacenan en una capa de caché para que se puedan utilizar local o remotamente en un entorno de agrupación de alta disponibilidad. En los entornos anteriores, los datos almacenados se modificaban directamente, pero en la capa de la caché, los datos se deben mover dentro y fuera de la caché a medida que se modifican. En un entorno de agrupación, la caché se distribuye. Por lo tanto, la latencia de red y la serialización de cables adicionales añaden tiempo a cada solicitud que se realiza.
El almacenamiento de grandes cantidades de datos en una propiedad como infotable es ahora muy caro y puede provocar fallos del sistema en entornos en clúster. Ahora, la infotable se lee completamente y se escribe en la propiedad cuando se cambia. En un entorno agrupado, el objeto completo también se serializa, se deserializa y se envía a través del cable. Las infotables de gran tamaño se deben mover a la base de datos, no almacenarse en una sola propiedad. Se pueden convertir en tablas definidas por el usuario o colocar en una tabla de datos.
En un entorno agrupado, se utiliza Apache Ignite. La inserción de objetos de gran tamaño puede hacer que Ignite deje de responder. Ignite pone en cola las escrituras y las copias de seguridad, y cuando se insertan valores de gran tamaño, puede tardar en controlarlos y hacer que el procesamiento retroceda. Si la copia de seguridad se hace grande, los subprocesos del sistema Ignite comenzarán a bloquearse, lo que puede hacer que Ignite cierre un nodo pensando que no responde. Los datos pueden ser cada vez más obsoletos.
Para trabajar bien en un entorno agrupado, es posible que sea necesario cambiar las aplicaciones para reducir el tamaño de los datos que se almacenan en las propiedades. Esto suele ser causado por infotables con miles de filas.
Ejemplo: clasificación de infotables
Este ejemplo solía funcionar antes de que se añadiera la capa de almacenamiento en caché. Se utiliza para actualizar directamente la tabla en la memoria.
var sort = new Object();
sort.name = yourFieldName;
sort.ascending = booleanValue;
me.yourInfoTable.Sort(sort);
Sin embargo, se debe realizar ahora de la siguiente manera:
Cree una infotable local, realice los cambios y vuelva a asignarla a la propiedad de infotable Cosa.
De este modo, se extraerá el objeto de la caché y se realizará una copia. A continuación, se puede cambiar la copia sin que afecte a la propiedad original hasta que se complete el conjunto.
Si esto no fuese cierto, cada vez que se tocase la infotable, todo el objeto se volvería a escribir en la caché, lo que provocaría una degradación del rendimiento.
var localInfoTable = me.yourInfoTable;
var sort = new Object();
sort.name = yourFieldName;
sort.ascending = booleanValue;
localInfoTable.Sort(sort);
me.yourInfoTable = localInfoTable;
Ejemplo: actualización de los valores de campo para infotables de una sola fila
Manera incorrecta:
Cada línea de este script obtendrá toda la infotable de la caché, cambiará un valor y, a continuación, volverá a colocar la infotable en la caché. Los recorridos de ida y vuelta a la caché tardan, debido a que se procesa toda la infotable cada vez. Se realizarán seis llamadas a la caché, que en un sistema remoto pueden ralentizar realmente el script.
Things["data1"].info.v1 = 1;
Things["data1"].info.v2 = 2;
Things["data1"].info.v3 = 3;
Manera correcta:
En este ejemplo se obtiene un clon de la infotable de la caché, se actualizan todos los datos localmente y, a continuación, se vuelve a colocar la infotable en la caché. De este modo, se reducen las llamadas a la caché a solo dos llamadas.
var myinfo = Things["data1"].info
myinfo.v1 = 1
myinfo.v2 = 2
myinfo.v3 = 3
Things["data1"].info = myinfo
Ejemplo: actualización de valores de campo en infotables de una sola fila
En el siguiente ejemplo, se muestra que cuando una infotable se asigna a una variable local, es un clon. Los cambios en el objeto original no se representarán en el valor clonado.
// creates a clone of InfoTable
var myinfo = Things["data1"].info;
// sets value of v1 to 5 in local InfoTable
myinfo.v1 = 5;
// change the orignal data1's v1 field value to 4, will not update the local value, it is still 5
Things["data1"].info.v1 = 4;
// assigning local info table to data2 so its v1 will have a value of 5
Things["data2"].info = myinfo;
Ejemplo: cambio de comportamiento con infotables de varias filas
A continuación, se puede ver que el clon de la infotable sigue siendo un objeto Proxy. Los métodos llamados en el objeto Proxy tendrán efecto en el objeto principal. Lo siguiente es coherente con el Proxy, pero difiere del comportamiento de ThingWorx 8.4. En ThingWorx 8.4, si se hiciera me.p2 = prop2, se rompería la referencia al objeto original. Esto no es el caso en ThingWorx 9, ya que se trata como el mismo Proxy de objeto.
// An InfoTable local object for the "v1" field
var newEntry = new Object();
newEntry.v1 = 1;
// creates a proxy object from local object prop1 -> me.p1
var prop1 = me.p1;
prop1.v1=4;
// creates a proxy object from local object prop2 -> me.p2
var prop2 = me.p2;
prop2.v1=5;
// updates the me.p1 object, this breaks the proxy between prop1 -> me.p1
me.p1=prop2;
// prop2 reference is unchanged, still proxied
me.p2=prop2;
// this will not change me.p1 since the reference was broken when the object assignement to prop2 was done
prop1.AddRow(newEntry);
// this will update me.p2, the object reference is the same
prop2.AddRow(newEntry);
Ejemplo: creación de una infotable de varias filas
En este ejemplo, se van a añadir filas a una infotable:
Manera incorrecta:
Aunque parece correcto porque se utiliza un método en la base de datos AddRow, realmente ese cambio se está redirigiendo mediante Proxy al objeto original para cada iteración del bucle. Esto hará que la infotable se escriba en la caché para todas las iteraciones del bucle, lo que no es deseable.
var myinfo = Things["data1"].info;
for (i=0; i < 10; i++) {
var row = new Object();
row.v1 = i;
row.v2 = i * 2;
row.v3 = i * 3;
myinfo.AddRow(row);
}
Things["data1"].info = myinfo;
Manera correcta:
En este ejemplo, se ha clonado el objeto para que se pueda manipular sin tener ningún efecto hasta que se vuelva a asignar al objeto original.
var myinfo = Resources["InfoTableFunctions"].Clone({ t1: Things["data1"].info });
for (i=0; i < 10; i++) {
var row = new Object();
row.v1 = i;
row.v2 = i * 2;
row.v3 = i * 3;
myinfo.AddRow(row);
}
Things["data1"].info = myinfo;
El siguiente ejemplo también funciona. Puesto que no se utilizan los métodos del objeto Proxy, no cambiará el objeto original hasta que se asigne.
var myinfo = Things["data1"].info;
for (i=0; i < 10; i++) {
var row = new Object();
row.v1 = i;
row.v2 = i * 2* 10;
row.v3 = i * 3* 100;
myinfo.rows[i] = row;
}
Things["data1"].info = myinfo;
¿Fue esto útil?