Quantcast
Channel: SCN: Message List - PowerBuilder Developer Center
Viewing all articles
Browse latest Browse all 7329

Re: Using SharedObject to call webservice in multithread

$
0
0

Hi everyone!

 

Duke: I'm not using here a webservice datawindow, but hope this helps.

 

First of all, this is what I'm trying to accomplish: I need to trigger a webservice, let the user interact with the screen and start retrieving the results on screen so the user can see:

 

1) if it stills running (because the webservice starts a multithread on the server to upload files (last month 120,000) to a content manager server.  If a file fails to be uploaded (it's not on the path,  has a different content from the e-sign one registered on database) the thread being used continues with the next one, if it gets an error that thread ends.  We record any of these situations on file and database so the user (a technical user) can take action.

 

2) which files are ready to do whatever the user need to do with them.

 

 

NOTE: this multithread (the example one) is used to execute different tasks, the webservice that I'm calling, internally uses multithread too but for the same task.

 

 

My development enviroment is:

Desktop app: PB 12.5.2 Build 5629 on a Windows 7 (64 bits)

Webservice: PB .Net 12.5.2 Build 5629 on a Windows Server Enterprise (32 bits)

 

 

This is my window:

 

cargaMultithread.png

 

Just as a reference:

 

Trámite / Servicio, Tipo de Docto. and Fuente are descriptor of the files.

Extensión del Docto.: is the file extension (as a reference for content manager server)

Ruta de Archivos a Subir: is the path of the files to be uploaded.

Ruta de Resultados: is the path for the XMLs with results of every file.

Secuencia del Proceso: is the ID of a massive process of e-signature where the files belong.

Folio Inicial and Folio Final: is the range of files to upload (the names are base on a sequence).

Usuario and Password del WS: User and password to authenticate on the webservice.

Inicio and Término: Start and Finish Date/Hour.

Exitosos: Filters files successfully uploaded on the below datawindow

Fallidos/Erróneos: Filters files that couldn't be uploaded.

 

 

Script:

 

*********************

*   User objects    *

*********************

 

  1) uo_bcfe_firma (that connects to webservice {uof_conectar} and triggers the method to upload the files {uof_subirDoctoMulti})

  NOTE: this NVO wraps all webservice methods (using its proxy)

 

 

  integer uof_conectar (string as_usuario, string as_pwd, string as_endpoint)

  --------------------------------------------------------------------

  long ll_log, ll_instance

 

  if isvalid(isoapconn_wsbcfe) then destroy(isoapconn_wsbcfe)

  if isvalid(iws_bcfews) then destroy(iws_bcfews)

  isoapconn_wsbcfe = create SoapConnection

  iws_bcfews = create uo_bcfews

 

  ll_log = isoapconn_wsbcfe.SetSoapLogFile ("mySoapLog.log")

 

  ll_instance = isoapconn_wsbcfe.CreateInstance(iws_bcfews,"uo_bcfeWS",as_endpoint) //My webservice proxy is "uo_bcfeWS"

 

  if ll_instance <> 0 then

  istr_error.error = -1

  istr_error.mensaje = 'No se pudo instanciar el Webservice'

  ib_conectado = FALSE

  return -1

  end if

 

  is_url = as_endpoint

  ib_conectado = TRUE

 

  return 0

 

 

  uof_subirDoctoMulti (str_bcfe_subirdocto_request astr_request, uo_pro03p_procesomasivo auo_resultados)

  ------------------------------------------------------------------------------------------------------

  this.uof_reset_error()

  istr_error.funcion = 'uof_subirDoctoMulti'

 

  try

 

  /* SI NO ESTA CONECTADO, CONECTARSE AL WEBSERVICE */

  if not  ib_conectado or astr_request.s_endpoint <> is_url then

       if this.uof_conectar(astr_request.s_usuario,astr_request.s_pwd,astr_request.s_endpoint) = -1 then

            auo_resultados.uof_mostrar_resultado(istr_error)

            return

       end if

       istr_error.funcion = 'uof_subirDoctoMulti'

  end if

 

  str_bcfesubirdocrequest lstr_request

  str_bcfeError lstr_error

 

  lstr_request = create str_bcfesubirdocrequest

  lstr_error = create str_bcfeError

 

  lstr_request.s_usuario = astr_request.s_usuario

  lstr_request.s_contrasenia = astr_request.s_pwd

  lstr_request.s_pathdoctos = astr_request.s_pathdocsubir

  lstr_request.s_pathresult = astr_request.s_pathresult

  lstr_request.i_tipotramite = astr_request.i_tipotramite

  lstr_request.i_tipotramitespecified = true

  lstr_request.i_tipodocto = astr_request.i_tipodocto

  lstr_request.i_tipodoctospecified = true

  lstr_request.i_fuente = astr_request.i_fuente

  lstr_request.i_fuentespecified = true

  lstr_request.s_secuencia = astr_request.s_secuencia

  lstr_request.s_ext = astr_request.s_ext

  lstr_request.s_folioini = astr_request.s_folioini

  lstr_request.s_foliofin = astr_request.s_foliofin

  lstr_request.s_rfchomo = astr_request.s_rfchomo

  lstr_request.b_fnfbit=astr_request.b_fnfbit

  lstr_request.b_fnfbitspecified = true

  lstr_request.b_buscarpendientes = astr_request.b_bpend

  lstr_request.b_buscarpendientesspecified = true

 

  lstr_error = iws_bcfews.subirdoctomulti(lstr_request) // Webservice Call

 

  istr_error.error = lstr_error.i_error             // Copy values from the proxy variables to the app variables (different standard)

  istr_error.mensaje = lstr_error.s_mensajeerror

 

  auo_resultados.uof_mostrar_resultado(istr_error) // Triggers callback function and sends error (if exists)


catch (soapException e)

       istr_error.error = -1

       istr_error.mensaje = e.text

       auo_resultados.uof_mostrar_resultado(istr_error)

       return

  end try

 

 

  2) uo_pro03p_procesomasivo (manages the callback)

 

  uof_setobject (window aw_invocador)

  ------------------------------------

  istr_error.funcion = 'uof_setobject'

  iw_ventana = aw_invocador             // iw_ventana is an instance window variable

 

 

  uof_mostrar_resultado (s_util_envia_error astr_error)

  ------------------------------------------------------

  istr_error.funcion = 'uof_mostrar_resultado'

iw_ventana.post dynamic event ue_callback(astr_error) // Triggers whatever script is on the window

 

 

 

*********************

*      Window      *

*********************

 

 

  wf_carga_masiva (when user hits "Procesar", input values are validated and then this function is called)

  --------------------------------------------------------------------------------------------------------

 

  /* OMITTED SCRIPT (NOT RELEVANT): 

    1) CLEARS VALUES ON DISPLAY FIELDS

    2) CLEANS VARIABLES FOR EVERY RUN

    3) GETS WEBSERVICE CONNECTION DATA

    4) SET START HOUR ON SCREEN

    5) SENDS A STARTING EMAIL TO THE USER

    6) ETC.      

  */

 

  /* MANDAR DISPARAR LA CARGA MASIVA */

  str_bcfe_subirdocto_request lstr_request

  iuo_signext = create uo_bcfe_firma   // NVO THAT CALLS THE WEBSERVICE

 

  /* VALORES FIJOS */

  lstr_request.s_endpoint = is_url

  lstr_request.s_usuario = sle_usrws.text

  lstr_request.s_pwd = sle_pwdws.text

  lstr_request.i_tipotramite = ii_tipotram

  lstr_request.i_tipodocto = ii_tipodoc

  lstr_request.i_fuente = ii_fuente

  lstr_request.s_pathdocsubir = sle_arcfirmar.text + '\'

  lstr_request.s_pathresult = sle_arcresult.text + '\'

  lstr_request.s_ext = dw_ext.uof_getvalueselected('extension')

  lstr_request.s_secuencia = em_secuencia.text

  lstr_request.s_folioini = em_secini.text

  lstr_request.s_foliofin = em_secfin.text

  lstr_request.b_fnfbit=cbx_filenotfound.checked

  lstr_request.b_bpend = cbx_bpend.checked

  guo_sesion.uof_obtiene_rfcusr(lstr_request.s_rfchomo)

 

  /* DISPARAR HILO ALTERNO */

  uo_pro03p_procesomasivo luo_comunicador1              // CALLBACK NVO

  luo_comunicador1 = create uo_pro03p_procesomasivo

  luo_comunicador1.uof_setobject( this )               // SETS THIS WINDOW AS THE INVOKER

 

  SharedObjectRegister("uo_bcfe_firma", "hilows")      // REGISTER NVO

SharedObjectGet("hilows",iuo_signext)

iuo_signext.post function uof_subirdoctomulti(lstr_request,luo_comunicador1) // TRIGGERS NVO METHOD THAT CALLS WEBSERVICE AND PASSES THE CALLBACK OBJECT INSTANCE

SharedObjectUnRegister('hilows')

 

  /* DESHABILITAR MENU */

  wf_habilita_menu(FALSE)  // DISABLES MENU AND HIDES TOOLBARITEMS SO USER CAN'T TRIGGER ANYTHING BUT KEEPS ACCESS TO RESULTS DATAWINDOW AND PRINT OPTION.

ib_wsCorriendo = true    // FLAG FOR WEBSERVICE TRIGGERED

timer(60,this)           // STARTS TIMER FOR RETRIEVING RESULTS (1 MINUTE FOR TESTING)

 

 

 

  ue_callback (windows user event)

  ------------------------------------------------------------------------

  s_util_envia_error lstr_errorCorreo

  string ls_vacio[]

 

timer(0) //stops timer

 

  if astr_error.error <> 0 then

 

    /* OMITTED SCRIPT       

      if webservice returns an error:

        * an email is sent

        * the triggered webservice flag is turn off (FALSE), so the window can be closed if needed.

        * menu are enabled (and its toolbaritems are shown)

        * error message is displayed on screen.

    */

 

  end if

 

  ib_wsCorriendo = false   //  the triggered webservice flag is turn off

  timer(60) // restart timer

 

                     

  timer (windows event)

  ------------------------------------------------------------------------

this.wf_traer_resultados()

 

 

wf_traer_resultados (windows event)

  ------------------------------------------------------------------------

 

  double ldb_max

  sle_refresh.text = string(now())    // SETS LAST REFRESHING TIME ON SCREEN

 

 

  /* TRAER LOS FOLIOS NUEVOS */

  if dw_result.rowcount() = 0 then         // IF THERES NOT RESULTS YET ON SCREEN LDB_MAX = 0 (RETRIEVES ONLY THE DIFFERENCE, USING MAX(FILEID) WHICH IS A SEQUENCE)

  ldb_max = 0

  dw_result.retrieve(is_secuencia, double(em_secini.text), double(em_secfin.text), ldb_max)

  else

  /* TRAERSE LOS FOLIOS DE DIFERENCIA Y COPIARLOS UNO POR UNO PARA DARLE EL EFECTO DE AVANCE */

  ldb_max = dw_result.getitemnumber(1,'maximo')

 

  openwithparm(w_dgi_espere,'Actualizando Resultados... ')

  setpointer(Hourglass!)

  idts_result.retrieve(is_secuencia, double(em_secini.text), double(em_secfin.text), ldb_max)  // GETS ONLY THE NEW RESULTS

  idts_result.rowscopy(1,idts_result.rowcount(),Primary!, dw_result,0, Primary!)           // AND COPIES THEM TO DW ON SCREEN

 

  if this.ib_wscorriendo or idb_maxAnt < ldb_max then  // DOESN'T STOP THE TIMER UNTIL TRIGGERED WS FLAG IS OFF AND GETS NO MORE RESULTS.

  if isvalid(w_dgi_espere) then close(w_dgi_espere)

  setpointer(Arrow!)

  idb_maxAnt = ldb_max

  else

  timer(0)

  /* OMITTED SCRIPT        

         * NOTIFIES THE END ON SCREEN AND WITH AN EMAIL

         * ENABLES AND SHOWS MENU         

       */           

  messagebox('Aviso','Proceso Terminado Exitosamente')     

  end if

  end if

 

  return 0


Viewing all articles
Browse latest Browse all 7329

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>