You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: expiry.go
    path of file: ./repos/gotosocial/internal/processing/polls
    
    the code of the file until where you have to start completion: // GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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
    
func (p *Processor) onExpiry(pollID string) func(context.Context, time.Time) {
	return func(ctx context.Context, now time.Time) {
		// Get the latest version of poll from database.
		poll, err := p.state.DB.GetPollByID(ctx, pollID)
		if err != nil {
			log.Errorf(ctx, "error getting poll %s from db: %v", pollID, err)
			return
		}

		if !poll.ClosedAt.IsZero() {
			// Expiry handler has already been run for this poll.
			log.Errorf(ctx, "poll %s already closed", pollID)
			return
		}

		// Extract status and
		// set its Poll field.
		status := poll.Status
		status.Poll = poll

		// Ensure the status is fully populated (we need the account)
		if err := p.state.DB.PopulateStatus(ctx, status); err != nil {
			log.Errorf(ctx, "error populating poll %s status: %v", pollID, err)

			if status.Account == nil {
				// cannot continue without
				// status account author.
				return
			}
		}

		// Set "closed" time.
		poll.ClosedAt = now
		poll.Closing = true

		// Update the Poll to mark it as closed in the database.
		if err := p.state.DB.UpdatePoll(ctx, poll, "closed_at"); err != nil {
			log.Errorf(ctx, "error updating poll %s in db: %v", pollID, err)
			return
		}

		// Enqueue a status update operation to the client API worker,
		// this will asynchronously send an update with the Poll close time.
		p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
			APActivityType: ap.ActivityUpdate,
			APObjectType:   ap.ObjectNote,
			GTSModel:       status,
			OriginAccount:  status.Account,
		})
	}
}