Il timeout dovrebbe essere una proprietà statica pubblica o un parametro per ogni funzione?

1

TLDR: TIMEOUT dovrebbe essere una proprietà pubblica sulla mia classe statica o un parametro per ogni funzione?

Sfondo: Sto rilasciando una libreria c # client-api che facilita la comunicazione con la nostra API REST.

Il client-api è costituito da un modello a oggetti e una grande classe statica con una serie di metodi di estensione richiesta per vari tipi. 10 circa% variazioni di% di co_de, alcuni% di.Get(),% di.Post(), ecc.

Questa classe statica piena di metodi di estensione è preconfigurata con il nostro URL del server e alcune altre costanti di configurazione statiche correlate alla connessione. Poiché tutte le funzionalità sono esposte tramite i metodi di estensione, non è necessario creare un'istanza di questa classe. Qualsiasi configurazione viene eseguita tramite proprietà statiche e influenza tutte le richieste effettuate dall'applicazione.

Problema:

Al momento, tutte le richieste utilizzano un timeout predefinito di 3 secondi (che sembra generoso per noi, dato che la nostra API deve essere molto reattiva.) Alcuni utenti con una cattiva connessione potrebbero voler aspettare più a lungo per una risposta.

La nostra soluzione rapida è di esporre il DEFAULT_TIMEOUT a una proprietà statica pubblica sulla classe che può essere impostata una sola volta durante l'inizializzazione, ma è la cosa giusta da fare per aggiungere un nuovo parametro opzionale a ciascuna delle nostre dozzine di metodi?

.Get(int timeout = DEFAULT_TIMEOUT) { ... }
.Get(..., int timeout = DEFAULT_TIMEOUT) { ... }
.Get(..., ..., int timeout = DEFAULT_TIMEOUT) { ... }
.Get(..., ..., ..., int timeout = DEFAULT_TIMEOUT) { ... }
...
.Post(..., int timeout = DEFAULT_TIMEOUT) { ... }
.Put(..., int timeout = DEFAULT_TIMEOUT) { ... }
.Save(..., int timeout = DEFAULT_TIMEOUT) { ... }
...

Da un lato, vogliamo essere flessibili a qualsiasi cosa il consumatore della nostra libreria client-API possa aver bisogno, ma d'altro canto, non voglio abituarmi ad inquinare ogni metodo con ogni parametro facoltativo che potrebbe avere un impatto su una richiesta (URL del server, token di autorizzazione, ecc.)

Quello che non voglio, è che l'utente senta la necessità di farlo:

ClientAPI.DEFAULT_TIMEOUT = 5000;
Thing found = new Thing(){ id = "19473" }.Get();
found.count += 1;
ClientAPI.DEFAULT_TIMEOUT = 20000;
found.Put();
ClientAPI.DEFAULT_TIMEOUT = 8000;
List<Widgets> widgets = found.GetSubresource("widgets");
...etc

È ragionevole supporre che gli utenti non saranno timeout di micromanaging per singole richieste del genere?

    
posta Alain 06.12.2013 - 21:20
fonte

4 risposte

3

Is it reasonable to assume users won't be micromanaging timeouts for individual requests like that?

Beh, in realtà dipende dai servizi forniti. Alcune operazioni potrebbero essere molto lente e il cliente potrebbe essere in grado di anticiparle (ad esempio, richiedere tutte le transazioni su alcuni account negli ultimi 5 anni) e l'utente è disposto ad attendere. Altre operazioni potrebbero non essere così lente, o l'utente potrebbe preferire fallire / abortire / saltare se sono troppo lenti. Penso che sia meglio dare loro l'opzione: magari impostare un valore "globale" predefinito quando creano per la prima volta l'oggetto client e consentire loro di eseguire l'override con un parametro facoltativo, come nell'esempio.

    
risposta data 06.12.2013 - 21:36
fonte
2

Mi dispiacerebbe avere solo un'impostazione statica globale, perché in un app è possibile avere un'unica impostazione di timeout e potrebbero esserci momenti in cui si desidera apportare tale variabile in tutta l'app. Questo è uno dei motivi per cui preferisco evitare implementazioni client API statiche a favore di implementazioni basate su istanze.

Un modo per gestirlo sarebbe aggiungere una configurazione fluente. Quindi i tuoi consumatori possono inserire qualcosa. IE puoi fare:

var r = ClientAPI.WithTimeout(30).GetResource()

E avere una semantica discreta senza ingombrare ogni chiamata di metodo con un mucchio di parametri facoltativi.

    
risposta data 06.12.2013 - 21:42
fonte
1

Bene, se insisti sulla gestione della funzionalità di timeout per la tua API, penso che l'impostazione statica abbia più senso.

Ma, personalmente, ritengo che la cosa migliore da fare sia consentire agli utenti della tua API di determinare il modo migliore per gestire i timeout. Non hai modo di sapere in quanti modi diversi gli utenti vorranno definire come gestire i timeout. Lo stesso con il caching, per esempio. I consumatori di API dovrebbero essere responsabili di questo genere di cose.

Togliti il carico dalle spalle e passa alla prossima funzione. :)

    
risposta data 06.12.2013 - 21:28
fonte
0

Suggerirei di avere la propria classe wrapper non statica, con timeout implementato come campo di istanza. Ecco come, ad esempio, HttpClient.TimeOut funziona. Gli utenti possono creare un'istanza statica della classe di servizio, se lo desiderano. Se necessario per la compatibilità all'indietro, sarebbe facile per te creare una classe statica che si comporta in modo identico alla classe corrente (cioè, la classe statica avrebbe un'istanza statica della tua nuova classe e chiamerebbe in essa per tutto).

Questo approccio ha numerosi vantaggi:
1. Evita di inquinare la firma del metodo.
2. Rende più facile l'esecuzione di test e l'iniezione delle dipendenze.
3. Riduce l'accoppiamento.

    
risposta data 07.12.2013 - 01:03
fonte

Leggi altre domande sui tag