Skip to content

Instantly share code, notes, and snippets.

@joseivanlopez
Last active March 3, 2025 14:38
Show Gist options
  • Save joseivanlopez/a8d1e4269e6f1c8d41837dfd89fb556d to your computer and use it in GitHub Desktop.
Save joseivanlopez/a8d1e4269e6f1c8d41837dfd89fb556d to your computer and use it in GitHub Desktop.

Challenges to solve with queries and hooks in storage

How to organize the model queries

In storage we have a JSON structure (model) and we need:

  • To get part of the model (e.g., a specific disk).
  • To get calculated information (e.g., whether a disk is the boot device).
  • To modify parts of the model (e.g., add a partition to a disk).

We need to decide how to structure the hooks, naming, etc.

For example:

const { data, isBootDevice } = useDeviceConfig("/dev/vda")
const { mutate } = useDeviceConfigMutation("/dev/vda")
mutate.addPatition(partitionConfig)
mutate.deletePartition(...)

Or having a more flat organization:

const driveConfig = useDriveConfig("/dev/vda")
const isBoot = isBootDevice("/dev/vda");
const addPartition = useAddPartition("/dev/vda");
const deletePartition = useDeletePartition("/dev/vda");
const setSpacePolicy = useSetSpacePolicy("/dev/vda");

How to define hooks that use other hooks

Let say we have a hook which returns the result of a query. For example, useDevices that returns the list of storage devices. And we need a recurrent calculation over the devices, for example, to get the disks containing any partition. Moreover, the result should always return the very same list object meanwhile the devices do not change. This would help to use the data as dependency in other hooks like useEffect or useMemo.

  • Should we use a new query which is automatically invalidated when useDevices gets invalidated?
  • Should we use a new hook which uses useMemo?
  • Other approach like utility methods instead of hooks?

How to react to changes

Let say we get an event when something happens, for example, when the storage probing is finished. And let say we have a hook (e.g., useProbeChanges) which invalidates the storage queries when that event happens.

How should we use such a hook? In a context? Individually in the required pages?

How to organize the queries

In storage we can classify the backend data depending on how long it lives:

  • Data that is invalidated when a proposal is calculated (e.g., config model).
  • Data that is invalidated when the system is probed (e.g., system devices).
  • Data that is invalidated when the product changes (i.e., everything).

We need to organize the queries to properly invalidate each set depending on the event or action.

@joseivanlopez
Copy link
Author

We agreed the following changes:

  • Use queries/ directory only for defining queries.
  • If a component needs to directly use a query, then call to #useQuery, #useSuspenseQuery or #useMutation.
  • Move hooks to hooks/ directory.
  • Define hooks for the storage model which return a "decorator" of the requested device (e.g., #useDrive).
  • The decorator returns an object of a new type/class diffent to the api type.
  • The decorator only contains read-only attributes/methods.
  • Define "mutation hooks" separately (e.g., useAddPartition, useSetSpacePolicy, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment