Ver Mensaje Individual
  #1  
Antiguo 10-04-2007
aprendiz2 aprendiz2 is offline
Miembro
 
Registrado: dic 2006
Posts: 70
Reputación: 18
aprendiz2 Va por buen camino
Multiusuario + Buffers = mal negocio...

Hola amigos !!! Ojala alguien pudiese mostrarme una solucion al siguiente problema:

Aparentemente Win... mantiene algunas operaciones de lectura escritura en buffers locales, cuando se esta leyendo / escribiendo a una unidad de red.

Esto es problematico si se esta trabajando en "multiusuario-concurrente" (asi se dice ? ), bueno, donde varios nodos accesan archivos de datos comunes, y toman decisiones basados en estos archivos centrales.

Ejemplo ( como comprobar este problema ):

Asumir que existen 2 PC en red local, y en una PC tenemos la unidad "K:" que se refiere al disco duro en la otra PC.

Si en el OnClick de un boton ponemos:

var F : File of char;
ch : char;
begin
AssignFile( F,'K:\ArchivoX.txt' );
Reset( F ); { Asumimos que ya existe ese archivo y contiene algo..}
Read( F, ch );
CloseFile( F );
end;

Entonces pruebe lo siguiente....

Con una mano, haga clic en el boton periodicamente...
Con la otra mano, ( sin hacer mucho ruido... ) desconecte el cable de red de esta maquina... mientras que con la otra mano usted sigue dando clics al mouse...

Que sucede...?

En teoria, el programa deberia dar un error tan pronto se desconecta el cable, pero no lo hace !!!. Sigue reportando que el archivo se lee correctamente !!!! Pruebelo y me dice...

( tendre un wireless en mi PC sin darme cuenta ? )

Ahora, pruebe cambiar la instruccion read( F,ch ), por un write(F,ch)
y hacemos lo mismo... ( comenzamos con el cable de red conectado, haciendo clics, y sigilosamente desconectamos el cable de red... )

El programa sigue corriendo bien !!!!. ( sera solo en mi PC que sucede esto ? )


Esto no es nada saludable para aplicaciones concurrentes multiusuario...
( a menos que todas esten solo leyendo datos que nunca cambian ! ).

Tambien se aplica a las tablas del BDE...

Asuma que tenemos una tabla en otra PC, y estamos conectados por una red.

Coloquemos la tabla en modo Cache,

y en un boton el Database.ApplyUpdates( ... )
al final del proceso de actualizacion puede ponerle Table1.Close si lo desea, lo cual daria la "ilusion" que realmente termino la transaccion y todo se grabo bien...

Ahora la prueba de fuego...algo diferente a la anterior ( algo drastica )

Mantenga una mano cerca del cable AC que alimenta a su PC.
Haga algun cambio a la tabla, dele clic al boton con el ApplyUpdates,

y despues que el boton haya salido...

desconecte el cabe de AC !!! ( apagado instantaneo ! ).

Ahora verifique la informacion en la otra PC....

Se actualizo ? no !!! permanecio igual !!! El cambio nunca llego. El cambio permance en la maquina fuente por un periodo de tiempo...antes de ser enviado a la otra...

Pruebe diferentes lapsos de tiempo... despues de darle clic al boton.. espere un segundo, o dos... y despues apague la PC... haga la prueba con 3 segundos de diferencia... asi averiguara el lapso de tiempo que se tarda en enviar los datos...

Pruebe con tablas que no estan en Cache.... se sorprendera...

Probando muchas cosas, solo he dado con un Table1.FlushBuffers, lo cual provoca envio instantaneo de la informacion, pero hace las operaciones con las tablas muuuuuuuuuuuy lentas.

En el caso de manejo de archivos en "binario", lo mismo, hay que andar buscando el handle de ese archivo, y llamar a un API de Win.. para hacer un flush... para medio garantizar que los datos lleguen a su destino en tiempo real, o proteste en caso que no se haya podido. Tambien se pone todo sumamente leeeeento...

Como se puede escribir un programa multi-usurario confiable con este comportamiento ? Los buffers son mal negocio en la concurrencia...

Delphi tiene buffers, Win mas buffers, la PC que recibe del otro lado de la red tiene mas buffers y el disco duro ha de tener una buena porcion de buffers tambien... a saber si manejados de buena forma o no...

Alguna buena solucion ?

Muy agradecido !
Responder Con Cita