¿Qué hay detrás de la plataforma "1C: Empresa"?

¡Hola, Habr!
En este artículo, comenzaremos a hablar sobre cómo está estructurada por dentro la plataforma '1C:Enterprise 8' y qué tecnologías se utilizan en su desarrollo.

¿Qué hay detrás de la plataforma "1C: Empresa"?

¿Por qué creemos que esto es interesante? En primer lugar, porque la plataforma '1C:Enterprise 8' es una gran aplicación (más de 10 millones de líneas de código) en C++ (cliente, servidor, etc.), JavaScript (cliente web) y, desde hace poco, también Java. Los grandes proyectos son interesantes precisamente por su escala, ya que los problemas que pasan desapercibidos en una pequeña base de código surgen con fuerza en tales proyectos. En segundo lugar, '1C:Enterprise' es un producto empaquetado y replicable, y hay muy pocos artículos sobre este tipo de desarrollos en Habr. Además, siempre es interesante saber cómo se vive en otros equipos y empresas.

Así que empecemos. En este artículo, daremos una visión general de algunas tecnologías que se utilizan en la plataforma, esbozaremos el panorama, sin profundizar demasiado en la implementación. Después de todo, para muchos mecanismos, un relato detallado podría requerir un artículo separado, y para algunos, ¡incluso un libro entero!
Para comenzar, es importante definir algunas cosas básicas: qué es la plataforma '1C:Enterprise' y de qué componentes se compone. La respuesta a esta pregunta no es tan sencilla, ya que bajo el término 'Plataforma' (por brevedad, la llamaremos así) se entiende tanto una herramienta para el desarrollo de aplicaciones comerciales como un entorno de ejecución y herramientas de administración. Podemos distinguir, de manera условной, los siguientes componentes:

  • clúster de servidores
  • 'cliente delgado' capaz de conectarse al servidor a través de http y de su propio protocolo binario
  • cliente para trabajar en una arquitectura de dos niveles con una base de datos ubicada en un disco duro o en una carpeta de red
  • cliente web
  • herramientas de administración del servidor de aplicaciones
  • entorno de desarrollo (conocido como Configurador)
  • entorno de ejecución para iOS, Android y Windows Phone (plataforma móvil 1C)

Todas estas partes, excepto el cliente web, están escritas en C++. Además, existe un recién anunciado Configurador de nueva generación, escrito en Java.

Aplicaciones nativas

Para el desarrollo de aplicaciones nativas se utiliza C++03. En Windows, el compilador usado es Microsoft Visual C++ 12 (perfil compatible con Windows XP), mientras que en Linux y Android se utiliza gcc 4.8, y para iOS — clang 5.0. La biblioteca estándar es única para todos los sistemas operativos y compiladores: STLPort. Esta solución reduce la probabilidad de errores específicos de la implementación de STL. Actualmente, planeamos cambiar a la implementación de STL proporcionada con CLang, ya que STLPort ha dejado de desarrollarse y no es compatible con el modo de soporte para C++11 en gcc.
La base de código del servidor es común en un 99%, y la del cliente en un 95%. Además, incluso la plataforma móvil utiliza el mismo código C++ que la versión 'grande', aunque el porcentaje de unificación es un poco más bajo allí.
Como la mayoría de los usuarios de C++, no nos pretendemos aprovechar del 100% de las capacidades del lenguaje y sus bibliotecas. Por ejemplo, prácticamente no utilizamos Boost, y entre las capacidades del lenguaje, la conversión de tipos dinámicos. Sin embargo, aplicamos activamente:

  • STL (en particular, cadenas, contenedores y algoritmos)
  • herencia múltiple, incluyendo la herencia múltiple de implementación
  • plantillas
  • excepciones
  • punteros inteligentes (implementación propia)

Mediante el uso de la herencia múltiple de interfaces (clases completamente abstractas), se hace posible un modelo de componentes, que se discutirá más adelante.

Componentes

Para garantizar la modularidad, todas las funcionalidades se dividen en componentes, que consisten en bibliotecas dinámicas (*.dll para Windows, *.so para Linux). En total, hay más de ciento cincuenta componentes, a continuación se presentan descripciones de algunos de ellos:

backend
Contiene el 'motor' de metadatos de la plataforma

accnt
Objetos que los desarrolladores de aplicaciones utilizan para construir la contabilidad (planes de cuentas y registros contables)

bsl
Motor de ejecución de un lenguaje embebido

nuke
Implementación propia de un asignador de memoria

dbeng8
Motor de base de datos de archivos. Máquina de base de datos sencilla orientada a archivos, basada en ISAM, que incluye también un simple procesador SQL

wbase
Contiene clases y funciones básicas para implementar la interfaz de usuario de Windows: clases de ventanas, acceso a GDI, etc.

La división en múltiples componentes es útil desde varios puntos de vista:

  • La división favorece un mejor diseño, en particular una mejor aislamiento del código
  • Con el conjunto de componentes se pueden armar diferentes opciones de entrega de manera flexible:
    • Por ejemplo, la instalación de un cliente ligero contendrá wbase, pero no tendrá backend
    • y en el servidor wbase, por el contrario, no estará presente
    • ambas opciones, por supuesto, contendrán nuke y bsl

Todos los componentes necesarios para esta opción de inicio se cargan al iniciar el programa. Esto, en particular, es necesario para registrar las clases SCOM, de las cuales se hablará más adelante.

SCOM

Para la descomposición a un nivel más bajo se utiliza el sistema SCOM, que es ideológicamente similar a la biblioteca ATL. Para aquellos que no han trabajado con ATL, se enumera brevemente las principales capacidades y características.
Para la clase SCOM especialmente diseñada:

  • Proporciona métodos de fábrica que permiten crear una clase a partir de otro componente conociendo solo su nombre (sin revelar la implementación)
  • Proporciona infraestructura de punteros inteligentes con conteo de referencias. No es necesario monitorear manualmente la vida útil de la clase SCOM
  • Permite conocer si un objeto implementa una interfaz específica y automáticamente convierte un puntero de objeto a un puntero de interfaz
  • Crear un objeto-servicio, siempre accesible a través del método get_service, etc.

Por ejemplo, se puede describir en el componente json.dll una clase para leer JSON (por ejemplo, JSONStreamReader).
Las clases, instancias se pueden crear a partir de otros componentes que deben registrarse en la máquina SCOM:

SCOM_CLASS_ENTRY(JSONStreamReader)

Este macro describirá una clase registradora estática especial, cuyo constructor será llamado al cargar el componente en memoria.
Después de esto, se puede crear su instancia en otro componente:

IJSONStreamReaderPtr jsonReader = create_instance<IJSONStreamReader>(SCOM_CLSIDOF(JSONStreamReader));

Para el soporte de servicios, SCOM ofrece una infraestructura adicional, bastante compleja. El concepto central es el proceso SCOM, que actúa como contenedor para los servicios en ejecución (es decir, cumple la función de Service Locator) y también contiene enlaces a recursos localizables. El proceso SCOM se vincula al hilo del sistema operativo. Gracias a esto, dentro de la aplicación se pueden obtener servicios de esta manera:

SCOM_Process* process = core::current_process();
if (process)
         return get_service<IMyService>(process);

Además, al alternar los procesos lógicos (SCOM) vinculados al flujo, se pueden obtener aplicaciones prácticamente independientes en términos de espacio de información, que se ejecutan dentro de un solo flujo. Así está diseñado nuestro cliente ligero, que trabaja con una base de archivos: dentro de un proceso del sistema operativo hay dos procesos SCOM, uno asociado al cliente y otro al servidor. Este enfoque permite unificar la escritura del código, que funcionará tanto en la base de archivos local como en la variante 'real' cliente-servidor. El precio de esta uniformidad son los gastos generales, pero la práctica demuestra que valen la pena.

Sobre la base del modelo de componentes SCOM se implementan tanto la lógica de negocio como la parte de interfaz de 1C: Enterprise.

Interfaz de usuario

Hablando de interfaces, no usamos los controles estándar de Windows, nuestros elementos de control están implementados directamente en la API de Windows. Para la versión de Linux, se ha creado una capa que funciona a través de la biblioteca wxWidgets.
La biblioteca de elementos de control no depende de otras partes de '1C: Enterprise' y se utiliza también en otras pequeñas utilidades internas.

A lo largo de los años de desarrollo de 1C: Enterprise, la apariencia de los controles ha cambiado, pero un cambio serio en los principios ocurrió solo una vez, en 2009, con el lanzamiento de la versión 8.2 y la aparición de las 'formas administradas'. Además del cambio en la apariencia, el principio de disposición de la forma ha cambiado fundamentalmente: se abandonó el posicionamiento pixel por pixel en favor de la disposición fluida de los elementos. Además, en el nuevo modelo, los elementos de control no interactúan directamente con los objetos de dominio, sino con DTO especiales (Data Transfer Objects).
Estos cambios han permitido crear un cliente web '1C: Enterprise' que replica la lógica de C++ de los controles en JavaScript. Nos esforzamos por mantener la equivalencia funcional entre los clientes ligero y web. En los casos en que esto no es posible, por ejemplo, debido a las limitaciones disponibles desde la API de JavaScript (por ejemplo, las capacidades para trabajar con archivos son muy limitadas), a menudo implementamos la funcionalidad necesaria mediante extensiones de navegador escritas en C++. Actualmente, soportamos Internet Explorer y Microsoft Edge (Windows), Google Chrome (Windows), Firefox (Windows y Linux) y Safari (MacOS).

Además, la tecnología de formularios gestionados se utiliza para crear la interfaz de aplicaciones móviles en la plataforma 1C. En dispositivos móviles, el renderizado de controles se realiza utilizando tecnologías 'nativas' para el sistema operativo, pero ya para la lógica de diseño del formulario y la respuesta de la interfaz se utiliza el mismo código que en la 'gran' plataforma '1C:Enterprise'.

¿Qué hay detrás de la plataforma "1C: Empresa"?
Interfaz 1C en el sistema operativo Linux

¿Qué hay detrás de la plataforma "1C: Empresa"?
Interfaz 1C en dispositivo móvil

Interfaz 1C en otras plataformas ¿Qué hay detrás de la plataforma "1C: Empresa"?
Interfaz 1C en el sistema operativo Windows

¿Qué hay detrás de la plataforma "1C: Empresa"?
Interfaz 1C — cliente web

Código abierto

Aunque no usamos las bibliotecas estándar para desarrolladores de C++ en Windows (MFC, controles de WinAPI), no todos los componentes los escribimos nosotros mismos. Ya se mencionó la biblioteca wxWidgets, además utilizamos:

  • cURL para trabajar con HTTP y FTP.
  • OpenSSL para trabajar con criptografía e instalaciones de conexiones TLS
  • libxml2 y libxslt para analizar XML
  • libetpan para trabajar con protocolos de correo (POP3, SMTP, IMAP)
  • mimetic para analizar mensajes de correo electrónico
  • sqllite para almacenar registros de actividad de los usuarios
  • ICU para la internacionalización

La lista aún se puede continuar.
Además, utilizamos versiones altamente modificadas de Google Test y Google Mock en el desarrollo de pruebas unitarias.
Las bibliotecas requirieron adaptación para ser compatibles con el modelo SCOM de organización de componentes.
La prevalencia de 1C hace que la plataforma sea una excelente prueba de resistencia para las bibliotecas que se utilizan en ella. La diversidad de usuarios y escenarios descubre rápidamente errores incluso en las secciones de código menos utilizadas. Los corregimos internamente y buscamos devolverlos a los autores de las bibliotecas. La experiencia de interacción resulta ser muy diversa.
Desarrolladores cURL y libetpan rápidamente responden a las pull-requests, pero el parche, por ejemplo, en OpenSSL no hemos podido devolverlo.

Conclusión

En este artículo hemos tocado algunos aspectos básicos del desarrollo de la plataforma '1C: Enterprise'. En el limitado alcance del artículo, hemos abordado solo algunos aspectos interesantes, a nuestro juicio.
Una descripción general de los diversos mecanismos de la plataforma se puede ver aquí.
¿Qué temas le gustaría ver en los próximos artículos?

¿Cómo se implementa la plataforma móvil 1C?
¿Descripción del funcionamiento interno del cliente web?
¿O quizás le interesa el proceso de selección de funciones para nuevas versiones, desarrollo y pruebas?

¡Escríbanos en los comentarios!

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster