In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Perdida conexion MariaDB

Foro de Xailer profesional en español
Responder
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Perdida conexion MariaDB

Mensaje por XeviCOMAS »

Dada una conexión...

WITH OBJECT oDs := TMariaDBDataSource():Create( Self )
:cHost := AppData:cXCM_DynDNS
:cUser := AppData:cUserXCM
:cPassword := AppData:cPassXCM

If :Connect()
aMisDatos := :QueryArray( "SELECT camp4 FROM xevi WHERE camp1 = '"+ Left(Application:cTitle,4) +"'" )
Else
msginfo( "Error" )
EndIf

Hasta ahí, bien... si se logra la conexión, se reciben los datos correctamente.
Ahora bien, después de unos minutos de inactividad, vuelvo a hacer una consulta más...

aMisDatos := oDs:QueryArray( "SELECT camp4 FROM xevi WHERE camp1 = '"+ Left(Application:cTitle,4) +"'" )

Y en algunos clientes, me lanza error de fallo en la conexión. En otros clientes siempre me funciona.

¿Hay alguna manera para saber si se ha perdido la conexión???

Algo así, como...

If !oDs:IsConnected() //Si está la conexión "muerta"
oDs:Connect() //Reconectar la conexión "perdida"
EndIf

aMisDatos := oDs:QueryArray( "SELECT camp4 FROM xevi WHERE camp1 = '"+ Left(Application:cTitle,4) +"'" )
Un Saludo,
Xevi.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9252
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Re: Perdida conexion MariaDB

Mensaje por ignacio »

Buenos días Xevi,

Te recomiendo que intentes disminuir el valor de nTimeOut para ver si de esa forma se ejecuta nuestro ping() interno que hacemos al servidor en cada consulta. Si te sigue fallando, lo más sencillo es incluir un timer que cada varios segundos haga una llamada a MYSQL_PING(). (ajusta el valor de los segundos hasta que no tengas ningún problema de conexión)

Saludos
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

Creo que no es por el nTimeOut, pues establecido por defecto a 1seg, creo que es lo "justo" y correcto.
Como parece ser que me está fallando en algun cliente que padece de micro-cortes en la fibra, no se, se me ocurre que antes de hacer cualquier consulta, verificar si la conexión todavía esta "viva" y si por algun caso no lo está, pues "reactivarla" reconectar.

Así, pues...

If MYSQL_PING( oDS:Handle ) > 0
oDs:Connect() //Reconectar la conexión "perdida"
EndIf

¿Estaria "correcto" ???

Gracias.
Un Saludo,
Xevi.
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

He creado un Timer para ir "refrescando" la vida del DataSource.
Me funciona, pero querria que éste, estuviera incorporado a la classe, y no me deja.

Código: Seleccionar todo

CLASS TMariaDBDataSource FROM XMariaDBDataSource
PUBLISHED:
   COMPONENT TimerPING
   METHOD New( oParent ) CONSTRUCTOR
ENDCLASS
METHOD New( oParent ) CLASS TMariaDBDataSource
   WITH OBJECT ::TimerPING := TTimer():New( self )
      :lEnabled := .F.
      :nInterval := 60000
      :OnTimer := {|oSender| MYSQL_PING( self:Handle ) }
      :Create()
   END
RETURN ::Super:New( oParent )
Me lanza error...

Código: Seleccionar todo

****************************** Registre d'errors ******************************

             Exe: D:\XeviXailer (local)\CWin\CWin.exe
         Version: 4.18.8.7
           Build: 7
       User name: Xevi
   Computer name: HPPORTATILI7
           Data: 16/09/2018
            Hora: 22:06:30
   Memòria lliure: 2097151
     Àrea actual: 1

-------------------------- Informació del compilador --------------------------

  Versió Xailer: Xailer 5.1.2
      Compilador: Harbour 3.2.0dev (r1503071916) 
Compilador C/C++: MinGW GNU C 4.9.2 (32-bit)
      Plataforma: Windows NT 10.0.16299

----------------------- Informació detallada del error ------------------------

      Subsistema: BASE
 Codi d'error: 1004
          Estat: .F.
     Descripció: Message not found
       Operació: TMariaDBDataSource:INSERTCOMPONENT
      Arguments:  [ 1] = Tipus: O Valor: 
         Fitxer: 
 Codi error SO: 0

Pila de trucades:
  __ERRRT_SBASE (0)
  TMARIADBDATASOURCE:ERROR (0)
  (b)HBOBJECT (0)
  TMARIADBDATASOURCE:MSGNOTFOUND (0)
  TMARIADBDATASOURCE:INSERTCOMPONENT (0)
  TTIMER:CREATE (71)
  TMARIADBDATASOURCE:NEW (1129)
  XDSOURCE (1087)
  XINICI (220)
  INICI (88)
  MAIN (22)
Un Saludo,
Xevi.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9252
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Re: Perdida conexion MariaDB

Mensaje por ignacio »

Buenos días,

Un objeto TTimer es un componente y su contenedor ha de ser un control capaz de manejarlos como sería un objeto TForm. Si no es el caso, lo más sencillo es no indicarle el oParent. Quita la referencia a Self en el constructor New().

Saludos

Nota: Es buena costumbre destruir el timer en el método Free() del TDataSource.
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

Código: Seleccionar todo

CLASS TMariaDBDataSource FROM XMariaDBDataSource
PUBLISHED:
   COMPONENT TimerPING
   METHOD New( oParent ) CONSTRUCTOR
ENDCLASS
METHOD New( oParent ) CLASS TMariaDBDataSource
   WITH OBJECT ::TimerPING := TTimer():New()
      :lEnabled := .F.
      :nInterval := 60000
      :OnTimer := {|oSender| MYSQL_PING( self:Handle ) }  //Aqui da error GPF
      :Create()
   END
RETURN ::Super:New( oParent )
Bien, así creo el Timer, pero, como hago el ping al Handle del DataSource ???
:OnTimer := {|oSender| MYSQL_PING( self:Handle ) } //Aqui da error GPF
:OnTimer := {|oSender| MYSQL_PING( oParent:Handle ) } //Aqui da error GPF
:OnTimer := {|oSender| MYSQL_PING( ::Super:Handle ) } //Aqui da error GPF

Gracias.
Un Saludo,
Xevi.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9252
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Re: Perdida conexion MariaDB

Mensaje por ignacio »

Buenos días,

Debería valer:

:OnTimer := {|oSender| MYSQL_PING( self:Handle ) }

O lo que es lo mismo:

:OnTimer := {|oSender| MYSQL_PING( ::Handle ) }

No obstante, has de cerciorarte de sólo ejecutar el Timer cuando la conexión se haya establecido y quitarla cuando la desconectes tu por código.

Saludos
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

este es el GPF que me lanza...

Código: Seleccionar todo

GPF (Code = c0000005):
Access violation
MYSQL_PING (0)
(b)TMARIADBDATASOURCE_NEW (1128)
TTIMER:ONTIMER (0)
(b)XTIMER (43)
TTIMER:WMTIMER (0)
MYSQL_PING (0)
(b)TMARIADBDATASOURCE_NEW (1128)
TTIMER:ONTIMER (0)
(b)XTIMER (43)
TTIMER:WMTIMER (0)
RUNFORM (0)
TAPPLICATION:RUN (287)
MAIN (23)
Un Saludo,
Xevi.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9252
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Re: Perdida conexion MariaDB

Mensaje por ignacio »

Código: Seleccionar todo

CLASS TMariaDBDataSource FROM XMariaDBDataSource

   DATA oTimer
   DATA nPings INIT 0

   METHOD Connect( cConnect )
   METHOD Disconnect()
   METHOD Destroy( lFree )

END CLASS

//--------------------------------------------------------------------------

METHOD Connect( cConnect ) CLASS TMariaDBDataSource

   LOCAL lOk

   lOk := ::Super:Connect( cConnect )

   IF lOk
      IF ::oTimer == NIL
         ::oTimer := TTimer():Create()
      ENDIF
      ::oTimer:nInterval := 1000
      ::oTimer:OnTimer := {|| MYSQL_PING( ::Handle ), ::nPings ++ }
      ::oTimer:lEnabled := .T.
   ENDIF

RETURN lOk

//--------------------------------------------------------------------------

METHOD DisConnect() CLASS TMariaDBDataSource

   IF ::oTimer != NIL
      ::oTimer:lEnabled := .F.
   ENDIF

RETURN ::Super:DisConnect()

//--------------------------------------------------------------------------

METHOD Destroy( lFree ) CLASS TMariaDBDataSource

   IF ::oTimer != NIL
      ::oTimer:End()
      ::oTimer := NIL
   ENDIF

RETURN ::Super:Destroy( lFree )
Adjuntos
TestMariaDB.zip
(2.56 KiB) Descargado 173 veces
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

Gracias Ignacio.

Código: Seleccionar todo

Compilant  TestMariaDB.prg...
Compilant  Form1.prg...
Enllaçant  TestMariaDB.exe...
C:\Xailer\Hb32\comp\mingw\Bin\ld: cannot find C:/Xailer/Hb32/comp/mingw/Lib/gcc/i686-w64-mingw32/7.3.0/crtbegin.o: No such file or directory
C:\Xailer\Hb32\comp\mingw\Bin\ld: cannot find -lgcc_eh
2 Files, 0 Warnings, 2 Errors
Temps de compilació: 6.49s   Temps d'enllaçat: 3.22s   Temp total: 9.74s
de todas formas, lo veo, estudio y lo incorporo en un proyecto nuevo con mi Xailer 5.1.2

Gracias.
Un Saludo,
Xevi.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9252
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Re: Perdida conexion MariaDB

Mensaje por ignacio »

Buenos días,

No creo que te cueste mucho cambiar la configuración del proyecto. No obstante, lo más rápido: en Propiedades del proyecto cambia de EXE a LIB y vuelvo a cambiarlo de LIB a EXE.

Saludos
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Perdida conexion MariaDB

Mensaje por XeviCOMAS »

Gracias, Ignacio... así de sencillo!!!

probado y funcionando perfectamente.
¿No seria "bueno" que la clase tuviera incorporado ese "timing" para mantener la conexión "viva" ???
Digo yo, a mi me está ocurrioendo con un cliente, que pierde la conexión a los 4min de no tocar nada... pero igual ese "timing" no compromete a nada en la clase y puede arreglar algun que otro corte que se pueda producir.

Añadiendo un nIntervalPING (yo lo pongo a los 30seg) si ése nIntervalPING > 0 que lanze el TimerPING

No se, igual es una tonteria, pero yo lo añado a la clase.

Muchas gracias.
Un Saludo,
Xevi.
Responder