Page 1 of 1

Perdida conexion MariaDB

Posted: Fri Sep 14, 2018 12:51 pm
by 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) +"'" )

Re: Perdida conexion MariaDB

Posted: Sat Sep 15, 2018 12:15 pm
by 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

Re: Perdida conexion MariaDB

Posted: Sat Sep 15, 2018 6:04 pm
by 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.

Re: Perdida conexion MariaDB

Posted: Sun Sep 16, 2018 10:09 pm
by 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.

Code: Select all

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...

Code: Select all

****************************** 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)

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 9:52 am
by 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.

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 11:37 am
by XeviCOMAS

Code: Select all

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.

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 12:09 pm
by 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

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 1:02 pm
by XeviCOMAS
este es el GPF que me lanza...

Code: Select all

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)

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 8:29 pm
by ignacio

Code: Select all

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 )

Re: Perdida conexion MariaDB

Posted: Mon Sep 17, 2018 10:44 pm
by XeviCOMAS
Gracias Ignacio.

Code: Select all

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.

Re: Perdida conexion MariaDB

Posted: Tue Sep 18, 2018 11:41 am
by 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

Re: Perdida conexion MariaDB

Posted: Tue Sep 18, 2018 12:32 pm
by 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.