In questi casi è utile la gestione di un semaforo per far lavorare i programmi uno alla volta: se trovo il semaforo rosso attendo il mio turno appena diventa verde.
Per esempio noi gestiamo la stampa delle etichette tramite l'applicazione NICELABEL: tutte le informazioni vengono scritte in un file, ma lo stesso file può essere scritto da programmi o utenti differenti; è importante gestire il fatto che non ci siano sovrapposizioni che porterebbero ad errori o inconsistenze.
La cosa più semplice è gestire il semaforo come l'esistenza di un file:
se il file esiste -> semaforo rosso
se il file non esiste -> semaforo verde
Uno dei pericoli in questi casi è che, per un errore o comunque una anomalia, un semaforo resti rosso (per qualche motivo non è stato cancellato il file) e tutte le elaborazioni successive risultano bloccate.
Una soluzione è quella di scrivere, all'interno del file, data e ora di creazione e un TTL (Time To Live), cioè il tempo di vita del semaforo: se il semaforo è rosso controllo quanto tempo è passato dalla creazione, se è superiore al TTL allora procedo come se il semaforo fosse verde.
Per tutta questa gestione ho costruito un Function Module SAP al quale viene passato:
Nome del file semaforo
operazione da eseguire (OPEN, CLOSE)
num.secondi attesa (default 2)
Numero di volte che provo ad accendere (default 5)
TTL
Nome FM Z_SEMAFORO
FUNCTION Z_SEMAFORO.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*" IMPORTING
*" REFERENCE(FILE_NAME) TYPE FILE_NAME
*" REFERENCE(OPERAZIONE) TYPE CHAR05
*" REFERENCE(WAIT_SEC) TYPE INT2 OPTIONAL
*" REFERENCE(NUM_CICLI) TYPE INT2 OPTIONAL
*" REFERENCE(TTL) TYPE INT4 OPTIONAL
*" EXPORTING
*" REFERENCE(ESITO) TYPE CHAR02
*" REFERENCE(MESSAGGIO) TYPE CHAR200
*"----------------------------------------------------------------------
* Autore : Fabio Giacobbe - 02/12/2016 |
* Descrizione: Gestione di un file semaforo. |
*----------------------------------------------------------------------+
* Modifiche : by |
* Note : |
*----------------------------------------------------------------------+
* parametri
* ingresso:
* FILE_NAME : Nome del file semaforo
* OPERAZIONE: operazione da eseguire
* - OPEN : accendi semaforo
* - CLOSE: spegni semaforo
* WAIT_SEC : num.secondi attesa (default 2)
* NUM_CICLI : Numero di volte che provo ad accendere (default 5)
* TTL : Nel file semaforo viene scritto:
* - data
* - ora
* - vita max in secondi
* Se il semaforo è acceso si controlla se la vita
* massima è già superata, nel caso si sovrascrive.
*
* uscita:
* ESITO : OK = operazione eseguita
* KO = operazione fallita
* MESSAGGIO : messaggio di errore
*----------------------------------------------------------------------+
* Descrizione funzionamento: lavora in base all'operazione da eseguire:
*
* OPEN: Si tenta di aprire il file passato in ingresso se:
* - il file non esiste: si scrive un nuovo file.
* - il file esiste: si legge la prima riga e si calcola da
* quanti secondi è stato creato. Quindi si verifica se il
* TTL (Time to live) è stato superato:
* - se è già stato superato si sovrascrive il file con
* i nuovi valori.
* - se invece non è stato superato si attende i secondi
* passati in ingresso e poi si tenta nuovamente (per
* il numero di volte passato in ingresso)
*
* CLOSE: Si cancella il file passato in ingresso.
*----------------------------------------------------------------------+
* Nota: Assicurarsi che gli utenti di servizio SAPservice<SID> abbiano
* accesso completo al percorso file.
*----------------------------------------------------------------------+
CASE operazione.
WHEN 'CLOSE'.
PERFORM spegni-semaforo USING file_name
esito
messaggio.
WHEN 'OPEN'.
WHEN OTHERS.
messaggio = text-001.
ENDCASE.
CHECK operazione = 'OPEN'.
data: wa_wait_sec type INT2,
wa_num_cicli type INT2,
wa_ttl type INT4,
wa_secondi type INT4,
wa_ttl_file type INT4.
Data: BEGIN OF record,
sysdate like sy-datum,
systime like sy-uzeit,
ttl(10),
end of record.
IF WAIT_SEC IS INITIAL.
wa_wait_sec = 2.
else.
wa_wait_sec = WAIT_SEC.
ENDIF.
IF NUM_CICLI IS INITIAL.
wa_num_cicli = 5.
else.
wa_num_cicli = NUM_CICLI.
ENDIF.
IF ttl IS INITIAL.
wa_ttl = wa_wait_sec * wa_num_cicli.
else.
wa_ttl = ttl.
ENDIF.
DO wa_num_cicli TIMES.
* verifico se il file esiste.
OPEN DATASET file_name FOR INPUT IN TEXT MODE ENCODING DEFAULT.
if sy-subrc <> 0.
PERFORM accendi-semaforo using file_name
wa_ttl
esito
messaggio.
EXIT.
endif.
* Il file esiste, leggo il contenuto e verifico se è superato il TTL
READ DATASET file_name into record.
CLOSE DATASET file_name.
wa_ttl_file = record-ttl.
CLEAR wa_secondi.
* calcolo la differenza in secondi tra data attuale e data file
CALL FUNCTION 'SALP_SM_CALC_TIME_DIFFERENCE'
EXPORTING
date_1 = sy-datum
time_1 = sy-uzeit
date_2 = record-sysdate
time_2 = record-systime
IMPORTING
SECONDS = wa_secondi
.
if wa_ttl_file < wa_secondi.
* il precedente file semaforo è già scaduto, pertanto scrivo nuovo file
PERFORM accendi-semaforo using file_name
wa_ttl
esito
messaggio.
EXIT.
endif.
WAIT UP TO wa_wait_sec SECONDS.
ENDDO.
ENDFUNCTION.
*&---------------------------------------------------------------------*
*& Form spegni semaforo
*&---------------------------------------------------------------------*
form spegni-semaforo USING file_name
esito
messaggio.
DELETE DATASET file_name.
IF sy-subrc = 0.
esito = 'OK'.
else.
esito = 'KO'.
ENDIF.
endform. " spegni-semaforo
*&---------------------------------------------------------------------*
*& Form accendi semaforo
*&---------------------------------------------------------------------*
form accendi-semaforo USING file_name
wa_ttl
esito
messaggio.
Data: BEGIN OF record,
sysdate like sy-datum,
systime like sy-uzeit,
ttl(10),
end of record.
record-sysdate = sy-datum.
record-systime = sy-uzeit.
write wa_ttl to record-ttl.
OPEN DATASET file_name FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
if sy-subrc <> 0.
esito = 'KO'.
messaggio = text-002.
else.
TRANSFER record TO file_name.
CLOSE DATASET file_name.
esito = 'OK'.
endif.
endform. " accendi-semaforo
Definizione testi:
text-001 Operazione semaforo non corretta!
text-002 Impossibile creare file semaforo
Parametri importazione:
Parametri esportazione:
esempio di chiamata alla funzione
CALL FUNCTION 'Z_SEMAFORO'
EXPORTING
file_name = wa_file_name
operazione = 'OPEN'
wait_sec = 5
num_cicli = 10
ttl = 60
* IMPORTING
* ESITO = wa_esito
* MESSAGGIO = wa_messaggio
.
EXPORTING
file_name = wa_file_name
operazione = 'OPEN'
wait_sec = 5
num_cicli = 10
ttl = 60
* IMPORTING
* ESITO = wa_esito
* MESSAGGIO = wa_messaggio
.
Nessun commento:
Posta un commento