func (r *XDLJobReconciler) Reconcile(request reconcile.Request) (reconcile.Result, error) {
	sharedXdlJob := &xdlv1alpha1.XDLJob{}
	err := util.GetObjectByPassCache(r.Client, request.NamespacedName, sharedXdlJob)
	if err != nil {
		if errors.IsNotFound(err) {
			log.Info("try to get job but it has been deleted", "key", request.String())
			r.ctrl.Metrics.DeletedInc()
			return reconcile.Result{}, nil
		}
		return reconcile.Result{}, err
	}
	xdlJob := sharedXdlJob.DeepCopy()
	needSync := r.ctrl.SatisfyExpectations(xdlJob, xdlJob.Spec.XDLReplicaSpecs)
	if !needSync || xdlJob.DeletionTimestamp != nil {
		log.Info("reconcile cancelled, job does not need to do reconcile or has been deleted",
			"sync", needSync, "deleted", xdlJob.DeletionTimestamp != nil)
		return reconcile.Result{}, nil
	}
	r.scheme.Default(xdlJob)
	result, err := r.ctrl.ReconcileJobs(xdlJob, xdlJob.Spec.XDLReplicaSpecs, xdlJob.Status, &xdlJob.Spec.RunPolicy, nil)
	if err != nil {
		log.Error(err, "xdl job reconcile failed.")
		return result, err
	}
	return result, err
}
Reconcile reads that state of the cluster for a XDLJob object and makes changes based on the state read
and what is in the XDLJob.Spec
+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete
+kubebuilder:rbac:groups="",resources=pods/status,verbs=get;update;patch
+kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete
+kubebuilder:rbac:groups="",resources=services/status,verbs=get;update;patch
+kubebuilder:rbac:groups="",resources=events,verbs=create
+kubebuilder:rbac:groups=scheduling.incubator.k8s.io;scheduling.sigs.dev;scheduling.volcano.sh,resources=podgroups;queues,verbs=*
+kubebuilder:rbac:groups=training.kubedl.io,resources=xdljobs,verbs=get;list;watch;create;update;patch;delete
+kubebuilder:rbac:groups=training.kubedl.io,resources=xdljobs/status,verbs=get;update;patch
package xdljob
import (
	"context"
	"fmt"
	"strings"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/tools/record"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"
	"sigs.k8s.io/controller-runtime/pkg/handler"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/predicate"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
	"sigs.k8s.io/controller-runtime/pkg/source"
	xdlv1alpha1 "github.com/alibaba/kubedl/apis/training/v1alpha1"
	"github.com/alibaba/kubedl/cmd/options"
	"github.com/alibaba/kubedl/pkg/gang_schedule/registry"
	"github.com/alibaba/kubedl/pkg/job_controller"
	v1 "github.com/alibaba/kubedl/pkg/job_controller/api/v1"
	"github.com/alibaba/kubedl/pkg/metrics"
	"github.com/alibaba/kubedl/pkg/util"
)
const (
	controllerName = "XDLController"
)
const (
	xdlConfig = "XDL_CONFIG"
	taskType  = "TASK_NAME"
	taskIndex = "TASK_INDEX"
	zkAddr    = "ZK_ADDR"
)
var log = logf.Log.WithName("xdl-controller")
func NewReconciler(mgr manager.Manager, config options.JobControllerConfiguration) *XDLJobReconciler {
	r := &XDLJobReconciler{
		Client: mgr.GetClient(),
		scheme: mgr.GetScheme(),
	}
	r.recorder = mgr.GetEventRecorderFor(r.ControllerName())
	r.ctrl = job_controller.NewJobController(r.Client, r, config, r.recorder, metrics.NewJobMetrics(xdlv1alpha1.XDLJobKind, r.Client))
	if r.ctrl.Config.EnableGangScheduling {
		r.ctrl.GangScheduler = registry.Get(r.ctrl.Config.GangSchedulerName)
	}
	return r
}
var _ reconcile.Reconciler = &XDLJobReconciler{}
var _ v1.ControllerInterface = &XDLJobReconciler{}
type XDLJobReconciler struct {
	client.Client
	scheme   *runtime.Scheme
	recorder record.EventRecorder
	ctrl     job_controller.JobController
}