Skip to content

Commit

Permalink
Improve error handling on data sync
Browse files Browse the repository at this point in the history
  • Loading branch information
WiIIiam278 committed Sep 22, 2023
1 parent b63e1bd commit 55e443c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,8 @@
public abstract class BukkitData implements Data {

@Override
public final void apply(@NotNull UserDataHolder dataHolder, @NotNull HuskSync plugin) {
final BukkitUser user = (BukkitUser) dataHolder;
try {
this.apply(user, (BukkitHuskSync) plugin);
} catch (Throwable e) {
plugin.log(Level.WARNING, String.format("[%s] Failed to apply %s data object; skipping",
user.getUsername(), this.getClass().getSimpleName()), e);
}
public final void apply(@NotNull UserDataHolder dataHolder, @NotNull HuskSync plugin) throws IllegalStateException {
this.apply((BukkitUser) dataHolder, (BukkitHuskSync) plugin);
}

public abstract void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

/**
* A holder of data in the form of {@link Data}s, which can be synced
Expand Down Expand Up @@ -83,22 +84,40 @@ default DataSnapshot.Packed createSnapshot(@NotNull DataSnapshot.SaveCause saveC
* The {@code runAfter} callback function will be run after the snapshot has been applied.
*
* @param snapshot the snapshot to apply
* @param runAfter the function to run asynchronously after the snapshot has been applied
* @param runAfter a consumer accepting a boolean value, indicating if the data was successfully applied,
* which will be run after the snapshot has been applied
* @since 3.0
*/
default void applySnapshot(@NotNull DataSnapshot.Packed snapshot, @NotNull ThrowingConsumer<UserDataHolder> runAfter) {
default void applySnapshot(@NotNull DataSnapshot.Packed snapshot, @NotNull ThrowingConsumer<Boolean> runAfter) {
final HuskSync plugin = getPlugin();
final DataSnapshot.Unpacked unpacked = snapshot.unpack(plugin);

// Unpack the snapshot
final DataSnapshot.Unpacked unpacked;
try {
unpacked = snapshot.unpack(plugin);
} catch (Throwable e) {
plugin.log(Level.SEVERE, String.format("Failed to unpack data snapshot for %s", getUsername()), e);
return;
}

// Synchronously attempt to apply the snapshot
plugin.runSync(() -> {
unpacked.getData().forEach((type, data) -> {
if (plugin.getSettings().isSyncFeatureEnabled(type)) {
if (type.isCustom()) {
getCustomDataStore().put(type, data);
try {
for (Map.Entry<Identifier, Data> entry : unpacked.getData().entrySet()) {
final Identifier identifier = entry.getKey();
if (plugin.getSettings().isSyncFeatureEnabled(identifier)) {
if (identifier.isCustom()) {
getCustomDataStore().put(identifier, entry.getValue());
}
entry.getValue().apply(this, plugin);
}
data.apply(this, plugin);
}
});
plugin.runAsync(() -> runAfter.accept(this));
} catch (Throwable e) {
plugin.log(Level.SEVERE, String.format("Failed to apply data snapshot to %s", getUsername()), e);
plugin.runAsync(() -> runAfter.accept(false));
return;
}
plugin.runAsync(() -> runAfter.accept(true));
});
}

Expand Down Expand Up @@ -157,6 +176,9 @@ default void setPersistentData(@NotNull Data.PersistentData persistentData) {
this.setData(Identifier.PERSISTENT_DATA, persistentData);
}

@NotNull
String getUsername();

@NotNull
Map<Identifier, Data> getCustomDataStore();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,14 @@ public abstract void showGui(@NotNull Data.Items.Items items, @NotNull MineDown
* Set a player's status from a {@link DataSnapshot}
*
* @param snapshot The {@link DataSnapshot} to set the player's status from
* @param cause The {@link DataSnapshot.UpdateCause} of the snapshot
* @since 3.0
*/
public void applySnapshot(@NotNull DataSnapshot.Packed snapshot, @NotNull DataSnapshot.UpdateCause cause) {
getPlugin().fireEvent(getPlugin().getPreSyncEvent(this, snapshot), (event) -> {
if (!isOffline()) {
UserDataHolder.super.applySnapshot(
event.getData(), (owner) -> completeSync(true, cause, getPlugin())
event.getData(), (succeeded) -> completeSync(succeeded, cause, getPlugin())
);
}
});
Expand Down

0 comments on commit 55e443c

Please sign in to comment.