C
C#•3mo ago
Torn

How would you abstract these two functions together most cleanly?

readonly LinkedList<Game> games = new();
readonly HashSet<int> ids = [];
int start = 0;
public int jsonExceptions;

public LinkedList<Game> Fetch(Func<LinkedList<Game>, bool> ContinueCondition) {
int retryCount = 0;
while (retryCount < 3) {
try {
while (AppendGames() && ContinueCondition(games)) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

FixDates();

return games;
}

public HashSet<int> FetchIDs() {
int retryCount = 0;
while (retryCount < 3) {
try {
while (AppendIDs()) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

return ids;
}
readonly LinkedList<Game> games = new();
readonly HashSet<int> ids = [];
int start = 0;
public int jsonExceptions;

public LinkedList<Game> Fetch(Func<LinkedList<Game>, bool> ContinueCondition) {
int retryCount = 0;
while (retryCount < 3) {
try {
while (AppendGames() && ContinueCondition(games)) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

FixDates();

return games;
}

public HashSet<int> FetchIDs() {
int retryCount = 0;
while (retryCount < 3) {
try {
while (AppendIDs()) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

return ids;
}
I feel bad about duplicating the code, but with different inputs and outputs, I'm not quite sure if there's a clean way to unduplicate this code.
2 Replies
Torn
TornOP•3mo ago
Does this seem reasonable?
public LinkedList<Game> FetchGames(Func<LinkedList<Game>, bool> ContinueCondition) => Fetch(games, games => AppendGames() && ContinueCondition(games), FixDates);
public LinkedList<Game> FetchGames() => FetchGames(_ => true);
public HashSet<int> FetchIDs() => Fetch(ids, _ => AppendIDs());

public T Fetch<T>(T collection, Func<T, bool> ContinueCondition, Action? Finalize = null) {
int retryCount = 0;
while (retryCount < 3) {
try {
while (ContinueCondition(collection)) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

Finalize?.Invoke();

return collection;
}
public LinkedList<Game> FetchGames(Func<LinkedList<Game>, bool> ContinueCondition) => Fetch(games, games => AppendGames() && ContinueCondition(games), FixDates);
public LinkedList<Game> FetchGames() => FetchGames(_ => true);
public HashSet<int> FetchIDs() => Fetch(ids, _ => AppendIDs());

public T Fetch<T>(T collection, Func<T, bool> ContinueCondition, Action? Finalize = null) {
int retryCount = 0;
while (retryCount < 3) {
try {
while (ContinueCondition(collection)) {
retryCount = 0;
}
break;
} catch (Exception ex) {
if (ex is JsonException) {
jsonExceptions++;
} else {
Log.Write($"Error while fetching games on entry {start}, retry {retryCount}:\n{ex}");
}
retryCount++;
System.Threading.Thread.Sleep(3000);
}
}

Finalize?.Invoke();

return collection;
}
FusedQyou
FusedQyou•3mo ago
Side point, if you're going to implement retries you might as well use Polly That said, why would you merge these? These two methods do something different and are only slightly related between eachother. Just keep them separate The only thing to abstract is the retry policy, which can be done using Polly 😛

Did you find this page helpful?