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: app_operations.go
    path of file: ./repos/heketi/apps/glusterfs
    
    the code of the file until where you have to start completion: //
// Copyright (c) 2018 The heketi Authors
//
// This file is licensed to you under your choice of the GNU Lesser
// General Public License, version 3 or any later version (LGPLv3 or
// later), or the GNU General Public License, version 2 (GPLv2), in all
// cases as published by the Free Software Foundation.
//

package glusterfs

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/boltdb/bolt"
	"github.com/gorilla/mux"

	"github.com/heketi/heketi/v10/pkg/glusterfs/api"
	"github.com/heketi/heketi/v10/pkg/utils"
)

func (a *App) AppOperationsInfo() (*api.OperationsInfo, error) {
	info := &api.OperationsInfo{}

	err := a.db.View(func(tx *bolt.Tx) error {
		ops, err := PendingOperationList(tx)
		if err != nil {
			return err
		}
		info.Total = uint64(len(ops))
	
    
func (a *App) PendingOperationCleanUp(w http.ResponseWriter, r *http.Request) {

	// Unmarshal JSON
	var msg api.PendingOperationsCleanRequest
	err := utils.GetJsonFromRequest(r, &msg)
	if err != nil {
		http.Error(w, "request unable to be parsed", 422)
		return
	}
	err = msg.Validate()
	if err != nil {
		http.Error(w, "validation failed: "+err.Error(), http.StatusBadRequest)
		logger.LogError("validation failed: " + err.Error())
		return
	}

	// create an ops-to-delete map from request
	// if this is empty we will attempt to clean *all* ops
	ops := map[string]bool{}
	for _, id := range msg.Operations {
		ops[id] = true
	}

	a.asyncManager.AsyncHttpRedirectFunc(w, r, func() (string, error) {
		err := a.OnDemandCleaner(ops).Clean()
		if err != nil {
			return "", err
		}
		return "", nil
	})
}