Re: SoC idea: desktop file cache



Hi guys, I had to give DBUS a try, so I went and modified the gdbus test
to get some numbers.

Running a thousand transactions takes about 1.5 seconds and there is no
big difference if the we transfer 50 bytes or 4 kbytes.

Here is the output of the test on my machine (Athlon 64 x2 5600+ with
DDR2 ram)

Took 3.020150 seconds to run 2000 iterations of 51 bytes each =
33773.156962 bytes/s

Took 3.193050 seconds to run 2000 iterations of 4079 bytes each =
2554923.975509 bytes/s

Took 0.081563 seconds to run 2 iterations of 1007029 bytes each =
24693280.041195 bytes/s

Took 0.752203 seconds to run 20 iterations of 1007029 bytes each =
26775458.220720 bytes/s

I assume here the bottle neck is the context switch between both server
and client.

So I think DBus speed wont be an issue transferring desktop entries to a
client.

my 2 cents

Juan Pablo
#include <gio/gio.h>
#include <stdlib.h>

/* ---------------------------------------------------------------------------------------------------- */

static GDBusNodeInfo *introspection_data = NULL;

/* Introspection data for the service we are exporting */
static const gchar introspection_xml[] =
  "<node>"
  "  <interface name='org.gtk.GDBus.TestPeerInterface'>"
  "    <method name='HelloWorld'>"
  "      <arg type='s' name='greeting' direction='in'/>"
  "      <arg type='s' name='response' direction='out'/>"
  "    </method>"
  "  </interface>"
  "</node>";

gint n_entries = 1;

/* ---------------------------------------------------------------------------------------------------- */
#define DESKTOP_ENTRY "[Desktop Entry]" \
"Exec=abiword"\
"Icon=abiword_48"\
"Terminal=false"\
"Type=Application"\
"Categories=Office;WordProcessor;GNOME;GTK;X-Red-Hat-Base;"\
"StartupNotify=true"\
"X-Desktop-File-Install-Version=0.9"\
"MimeType=application/x-abiword;text/x-abiword;text/x-xml-abiword;text/plain;application/msword;application/rtf;"\
"application/vnd.plain;application/xhtml+xml;text/html;application/x-crossmark;application/docbook+xml;application/x-t602;application/vnd.oasis.opendocument.text;"\
"application/vnd.oasis.opendocument.text-template;application/vnd.oasis.opendocument.text-web;application/vnd.sun.xml.writer;application/vnd.stardivision.writer;"\
"text/vnd.wap.wml;application/wordperfect6;application/wordperfect5.1;application/vnd.wordperfect;application/x-abicollab;application/vnd.palm;application/x-applix-word;"\
"application/x-kword;application/x-mif;application/x-mswrite;application/x-palm-database;text/abiword;text/richtext;text/rtf;application/x-abicollab"\
"Name=AbiWord"\
"GenericName=Word Processor"\
"Comment=Compose, edit, and view documents"
static void
handle_method_call (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *interface_name,
                    const gchar           *method_name,
                    GVariant              *parameters,
                    GDBusMethodInvocation *invocation,
                    gpointer               user_data)
{
  if (g_strcmp0 (method_name, "HelloWorld") == 0)
    {
      const gchar *greeting;
      GString *str;
      gchar *response;
      gint i;
      
      g_variant_get (parameters, "(&s)", &greeting);
      response = g_strdup_printf ("You said '%s'. KTHXBYE!\n", greeting);

      str = g_string_new (greeting);

      for (i = 0; i < n_entries; i++)
        g_string_append (str, DESKTOP_ENTRY);
      
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(s)", str->str));
      g_free (response);
      g_string_free (str, TRUE);
//      g_print ("Client said: %s\n", greeting);
    }
}

static const GDBusInterfaceVTable interface_vtable =
{
  handle_method_call,
  NULL,
  NULL,
};

/* ---------------------------------------------------------------------------------------------------- */

static gboolean
on_new_connection (GDBusServer *server,
                   GDBusConnection *connection,
                   gpointer user_data)
{
  guint registration_id;
  GCredentials *credentials;
  gchar *s;

  credentials = g_dbus_connection_get_peer_credentials (connection);
  if (credentials == NULL)
    s = g_strdup ("(no credentials received)");
  else
    s = g_credentials_to_string (credentials);


  g_print ("Client connected.\n"
           "Peer credentials: %s\n"
           "Negotiated capabilities: unix-fd-passing=%d\n",
           s,
           g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);

  g_object_ref (connection);
  registration_id = g_dbus_connection_register_object (connection,
                                                       "/org/gtk/GDBus/TestObject",
                                                       introspection_data->interfaces[0],
                                                       &interface_vtable,
                                                       NULL,  /* user_data */
                                                       NULL,  /* user_data_free_func */
                                                       NULL); /* GError** */
  g_assert (registration_id > 0);

  return TRUE;
}

/* ---------------------------------------------------------------------------------------------------- */

int
main (int argc, char *argv[])
{
  gint ret;
  gboolean opt_server;
  gchar *opt_address;
  GOptionContext *opt_context;
  gboolean opt_allow_anonymous;
  gint i, n_times = 1;
  GError *error;
  GTimer *timer;
  gdouble elapsed;
  GOptionEntry opt_entries[] =
    {
      { "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL },
      { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL },
      { "iteration-size", 'i', 0, G_OPTION_ARG_INT, &n_times, "Number of iterations to run on the client", NULL },
      { "entries", 'e', 0, G_OPTION_ARG_INT, &n_entries, "Number of desktop entries to inlude in server response", NULL },
      { "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL },
      { NULL}
    };

  ret = 1;

  g_type_init ();

  opt_address = NULL;
  opt_server = FALSE;
  opt_allow_anonymous = FALSE;

  opt_context = g_option_context_new ("peer-to-peer example");
  error = NULL;
  g_option_context_add_main_entries (opt_context, opt_entries, NULL);
  if (!g_option_context_parse (opt_context, &argc, &argv, &error))
    {
      g_printerr ("Error parsing options: %s\n", error->message);
      g_error_free (error);
      goto out;
    }
  if (opt_address == NULL)
    {
      g_printerr ("Incorrect usage, try --help.\n");
      goto out;
    }
  if (!opt_server && opt_allow_anonymous)
    {
      g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n");
      goto out;
    }

  /* We are lazy here - we don't want to manually provide
   * the introspection data structures - so we just build
   * them from XML.
   */
  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
  g_assert (introspection_data != NULL);

  if (opt_server)
    {
      GDBusServer *server;
      gchar *guid;
      GMainLoop *loop;
      GDBusServerFlags server_flags;

      guid = g_dbus_generate_guid ();

      server_flags = G_DBUS_SERVER_FLAGS_NONE;
      if (opt_allow_anonymous)
        server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;

      error = NULL;
      server = g_dbus_server_new_sync (opt_address,
                                       server_flags,
                                       guid,
                                       NULL, /* GDBusAuthObserver */
                                       NULL, /* GCancellable */
                                       &error);
      g_dbus_server_start (server);
      g_free (guid);

      if (server == NULL)
        {
          g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message);
          g_error_free (error);
          goto out;
        }
      g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server));
      g_signal_connect (server,
                        "new-connection",
                        G_CALLBACK (on_new_connection),
                        NULL);

      loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (loop);

      g_object_unref (server);
      g_main_loop_unref (loop);
    }
  else
    {
      GDBusConnection *connection;
      const gchar *greeting_response;
      GVariant *value;
      gchar *greeting;
      gint len;

      error = NULL;
      connection = g_dbus_connection_new_for_address_sync (opt_address,
                                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                                           NULL, /* GDBusAuthObserver */
                                                           NULL, /* GCancellable */
                                                           &error);
      if (connection == NULL)
        {
          g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message);
          g_error_free (error);
          goto out;
        }

      g_print ("Connected.\n"
               "Negotiated capabilities: unix-fd-passing=%d\n",
               g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);

      greeting = g_strdup_printf ("Hey, it's %" G_GUINT64_FORMAT " already!", (guint64) time (NULL));
      
      timer = g_timer_new ();
      for (i = 0; i < n_times; i++)
        {
          value = g_dbus_connection_call_sync (connection,
                                               NULL, /* bus_name */
                                               "/org/gtk/GDBus/TestObject",
                                               "org.gtk.GDBus.TestPeerInterface",
                                               "HelloWorld",
                                               g_variant_new ("(s)", greeting),
                                               G_VARIANT_TYPE ("(s)"),
                                               G_DBUS_CALL_FLAGS_NONE,
                                               -1,
                                               NULL,
                                               &error);
          if (value == NULL)
            {
              g_printerr ("Error invoking HelloWorld(): %s\n", error->message);
              g_error_free (error);
              goto out;
            }
        }
      g_timer_stop (timer);
      elapsed = g_timer_elapsed (timer, NULL);
      g_variant_get (value, "(&s)", &greeting_response);
      len = strlen (greeting_response);
      g_print ("Took %lf seconds to run %d iterations of %d bytes each = %lf bytes/s\n",
               elapsed, n_times, len, (len*n_times)/elapsed);
      g_variant_unref (value);

      g_object_unref (connection);
    }
  g_dbus_node_info_unref (introspection_data);

  ret = 0;

 out:
  return ret;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]