- En la versión 0.15 de Zig se introdujo la nueva interfaz de IO (
std.Io.Reader, std.Io.Writer)
- El objetivo era mejorar la complejidad del enfoque anterior de IO y sus problemas de rendimiento, pero en la práctica ha generado confusión sobre cómo usarla
- En el uso de
tls.Client y los buffers, la forma inconsistente de pasar parámetros aumenta aún más la confusión
- Incluso al implementar ejemplos básicos de uso, hay requisitos complejos como definir varios tamaños de buffer y campos de opciones
- La falta de documentación oficial, ejemplos de código y funciones de conveniencia hace que no sea intuitiva para principiantes
La nueva interfaz de IO introducida en Zig 0.15 y su contexto
- En la versión 0.15 de Zig se introdujeron los nuevos tipos de IO
std.Io.Reader y std.Io.Writer
- La interfaz anterior de IO generaba complejidad por problemas de rendimiento, mezcla de tipos y uso excesivo de
anytype
- Los objetivos principales de la nueva estructura de IO son una separación clara de tipos entre interfaces y una mejora del rendimiento
Problemas reales al usar tls.Client y la interfaz de IO
- Durante la actualización de una librería SMTP existente surgió confusión con la forma de usar la función
tls.Client.init
- Según la documentación, la función
init recibe como argumentos punteros a Reader y Writer, además de un conjunto de opciones
- En Zig,
net.Stream devuelve Stream.Reader y Stream.Writer mediante los métodos reader() y writer()
- Sin embargo,
Stream.Reader/Writer y std.Io.Reader/Writer no son exactamente el mismo tipo, por lo que hace falta una conversión
- En
Reader hay que llamar al método interface(), mientras que en Writer se debe usar el campo &interface, lo que muestra una falta de consistencia
Problemas con la configuración de buffers y campos de opciones
stream.writer y stream.reader reciben un buffer como argumento, respectivamente
- Se resalta que el buffer es un elemento esencial en la nueva interfaz de IO
- Al llamar a
tls.Client.init, se requieren obligatoriamente cuatro campos de opciones: ca_bundle, host, write_buffer y read_buffer
- La regla para separar qué valores se pasan dentro del parámetro de opciones y cuáles se pasan directamente como argumentos se siente poco clara
var tls_client = try std.crypto.tls.Client.init(
reader.interface(),
&writer.interface,
.{
.ca = .{.bundle = bundle},
.host = .{ .explicit = "www.openmymind.net" } ,
.read_buffer = &read_buf2,
.write_buffer = &write_buf2,
},
)
- En la práctica, si no se proporcionan correctamente los punteros a los buffers, el programa puede dejar de funcionar bien o presentar problemas como bloqueos o fallos
Problemas de intuición al usar Reader
- Aunque el campo
reader de tls.Client en sí representa un "flujo desencriptado", en realidad std.Io.Reader no tiene un método read convencional
- En su lugar, solo ofrece métodos menos intuitivos como
peek, takeByteSigned y readSliceShort
- La API más cercana a un uso práctico termina siendo leer datos a un buffer mediante el método
stream
var buf: [1024]u8 = undefined;
var w: std.Io.Writer = .fixed(&buf);
const n = try tls_client.reader.stream(&w, .limited(buf.len));
Ejemplo de código completo y problemas en la práctica
- Incluso al intentar crear un ejemplo mínimo completamente funcional, hay muchos detalles a considerar, como opciones, tamaños de buffer y conversiones de tipos
- La falta de pruebas, documentación y ejemplos eleva la dificultad de aprendizaje y la barrera de entrada
- Si no se comprende bien la consistencia interna del lenguaje Zig o su diseño subyacente, hay muchos puntos que pueden sentirse extraños
- Incluso dentro de la librería estándar este enfoque no se usa demasiado, así que faltan referencias prácticas para casos reales
Experiencia y conclusión
- Cambios de nombres como
std.fmt.printInt y variaciones en el diseño de la API hacen que el proceso de migración en sí no sea sencillo
- Se repiten varias dificultades, como el uso de
reader.interface(), &writer.interface, la forma de pasar opciones y la necesidad de múltiples buffers
- Desde la perspectiva de alguien que no está familiarizado con protocolos de red y seguridad como TLS, entender los requisitos se vuelve aún más difícil
- En conjunto, todavía existen varias carencias en términos de claridad, documentación y mejora de la comodidad de uso frente al enfoque anterior
Aún no hay comentarios.