<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def WriteClientStartupInfo(self, client_id, new_si):
 """Handle a startup event."""

    drift = rdfvalue.Duration("5m")

    if data_store.RelationalDBEnabled():
      current_si = data_store.REL_DB.ReadClientStartupInfo(client_id)

      # We write the updated record if the client_info has any changes
      # or the boot time is more than 5 minutes different.
      if (not current_si or current_si.client_info != new_si.client_info or
          not current_si.boot_time or
          abs(current_si.boot_time - new_si.boot_time) > drift):
        try:
          data_store.REL_DB.WriteClientStartupInfo(client_id, new_si)
        except db.UnknownClientError:
          # On first contact with a new client, this write will fail.
          logging.info("Can't write StartupInfo for unknown client %s",
                       client_id)
    else:
      changes = False
      with aff4.FACTORY.Create(
          client_id, aff4_grr.VFSGRRClient, mode="rw",
          token=self.token) as client:
        old_info = client.Get(client.Schema.CLIENT_INFO)
        old_boot = client.Get(client.Schema.LAST_BOOT_TIME, 0)

        info = new_si.client_info

        # Only write to the datastore if we have new information.
        if info != old_info:
          client.Set(client.Schema.CLIENT_INFO(info))
          changes = True

        client.AddLabels(info.labels, owner="GRR")

        # Allow for some drift in the boot times (5 minutes).
        if not old_boot or abs(old_boot - new_si.boot_time) > drift:
          client.Set(client.Schema.LAST_BOOT_TIME(new_si.boot_time))
          changes = True

      if data_store.RelationalDBEnabled() and changes:
        try:
          data_store.REL_DB.WriteClientStartupInfo(client_id, new_si)
        except db.UnknownClientError:
          pass