*
* Copyright 2026 Eva M
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#define G_LOG_DOMAIN "BAZAAR::REFRESH-WORKER"
#include "bz-backend-notification.h"
#include "bz-backend.h"
#include "bz-entry-cache-manager.h"
#include "bz-flatpak-instance.h"
#include "env.h"
#include "util.h"
#include "refresh-worker.h"
BZ_DEFINE_DATA (
main,
Main,
{
GMainLoop *loop;
int rv;
},
BZ_RELEASE_DATA (loop, g_main_loop_unref));
static DexFuture *
run (MainData *data);
int
run_refresh_worker (int argc,
char *argv[])
{
g_autoptr (GMainLoop) main_loop = NULL;
g_autoptr (MainData) data = NULL;
g_autoptr (DexFuture) future = NULL;
main_loop = g_main_loop_new (NULL, FALSE);
data = main_data_new ();
data->loop = g_main_loop_ref (main_loop);
data->rv = EXIT_SUCCESS;
future = dex_scheduler_spawn (
dex_scheduler_get_default (),
bz_get_dex_stack_size (),
(DexFiberFunc) run,
main_data_ref (data), main_data_unref);
g_main_loop_run (main_loop);
return data->rv;
}
static DexFuture *
run (MainData *data)
{
gboolean result = FALSE;
g_autoptr (GError) local_error = NULL;
g_autoptr (BzEntryCacheManager) cache = NULL;
g_autoptr (BzFlatpakInstance) flatpak = NULL;
g_autoptr (DexChannel) channel = NULL;
g_autoptr (GHashTable) installed_set = NULL;
g_autoptr (DexFuture) all_notifs = NULL;
guint n_notifs = 0;
g_autoptr (GPtrArray) write_backs = NULL;
cache = bz_entry_cache_manager_new ();
flatpak = dex_await_object (
bz_flatpak_instance_new (),
&local_error);
if (flatpak == NULL)
goto err;
channel = bz_backend_create_notification_channel (BZ_BACKEND (flatpak));
if (channel == NULL)
goto err;
result = dex_await (
bz_backend_retrieve_remote_entries (
BZ_BACKEND (flatpak), NULL),
&local_error);
if (!result)
goto err;
installed_set = dex_await_boxed (
bz_backend_retrieve_install_ids (
BZ_BACKEND (flatpak), NULL),
&local_error);
if (installed_set == NULL)
goto err;
all_notifs = dex_channel_receive_all (channel);
n_notifs = dex_future_set_get_size (DEX_FUTURE_SET (all_notifs));
write_backs = g_ptr_array_new_with_free_func (dex_unref);
for (guint i = 0; i < n_notifs; i++)
{
DexFuture *future = NULL;
g_autoptr (BzBackendNotification) notif = NULL;
BzBackendNotificationKind kind = 0;
future = dex_future_set_get_future_at (
DEX_FUTURE_SET (all_notifs), i);
notif = dex_await_object (dex_ref (future), NULL);
if (notif == NULL)
continue;
kind = bz_backend_notification_get_kind (notif);
if (kind == BZ_BACKEND_NOTIFICATION_KIND_REPLACE_ENTRY)
{
BzEntry *entry = NULL;
const char *unique_id = NULL;
entry = bz_backend_notification_get_entry (notif);
unique_id = bz_entry_get_unique_id (entry);
bz_entry_set_installed (entry, g_hash_table_contains (installed_set, unique_id));
g_ptr_array_add (
write_backs,
bz_entry_cache_manager_add (cache, entry));
}
}
if (write_backs->len > 0)
dex_await (
dex_future_allv (
(DexFuture *const *) write_backs->pdata,
write_backs->len),
NULL);
data->rv = EXIT_SUCCESS;
g_main_loop_quit (data->loop);
return dex_future_new_true ();
err:
if (local_error != NULL)
g_critical ("Unable to complete refresh: %s", local_error->message);
data->rv = EXIT_FAILURE;
g_main_loop_quit (data->loop);
return dex_future_new_false ();
}