func (h *Handler) UpdateSession(product, productPassword, clientKey string,
	units uint64, stopSession bool) error {
	logger := h.logger.Add("method", "UpdateSession", "product", product,
		"clientKey", clientKey, "units", units,
		"stopSession", stopSession)

	if stopSession {
		logger.Info("session stop request")
	} else {
		logger.Info("session update request")
	}

	prod, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return err
	}

	ch, err := h.findClientChannel(logger, prod, clientKey, true)
	if err != nil {
		return err
	}

	// Make the server adapter to kill the session for non-active channel.
	if prod.IsServer && ch.ServiceStatus != data.ServiceActive {
		logger.Warn("non-active channel")
		return ErrNonActiveChannel
	}

	clientStop := !prod.IsServer && stopSession

	if clientStop {
		if ch.ServiceStatus == data.ServiceTerminated {
			logger.Warn("already terminated channel")
			return nil
		}

		status := data.ServiceSuspended
		if ch.ServiceStatus == data.ServiceTerminating {
			status = data.ServiceTerminated
		}

		err := job.AddWithData(h.queue, nil,
			data.JobClientCompleteServiceTransition,
			data.JobChannel, ch.ID, data.JobSessionServer,
			status)
		if err != nil && err != job.ErrDuplicatedJob {
			logger.Error(err.Error())
			return err
		}
	}

	sess, err := h.findCurrentSession(logger, ch.ID)
	if err != nil {
		// Client adapter can signal failure immediately, when no
		// session is yet created.
		if err == ErrSessionNotFound && clientStop {
			return nil
		}
		return err
	}
	logger = logger.Add("session", sess)

	if units != 0 {
		// TODO: Use unit size instead of this hardcode.
		units /= 1024 * 1024

		switch prod.UsageRepType {
		case data.ProductUsageIncremental:
			sess.UnitsUsed += units
		case data.ProductUsageTotal:
			sess.UnitsUsed = units
		default:
			logger.Fatal("unsupported product usage")
		}
	}

	sess.LastUsageTime = time.Now()
	if stopSession {
		sess.Stopped = pointer.ToTime(sess.LastUsageTime)
	}

	logger.Info("updating session")

	if err := h.db.Save(sess); err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	return nil
}
func (h *Handler) UpdateSession(product, productPassword, clientKey string,
	units uint64, stopSession bool) error {
	logger := h.logger.Add("method", "UpdateSession", "product", product,
		"clientKey", clientKey, "units", units,
		"stopSession", stopSession)

	if stopSession {
		logger.Info("session stop request")
	} else {
		logger.Info("session update request")
	}

	prod, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return err
	}

	ch, err := h.findClientChannel(logger, prod, clientKey, true)
	if err != nil {
		return err
	}

	
	if prod.IsServer && ch.ServiceStatus != data.ServiceActive {
		logger.Warn("non-active channel")
		return ErrNonActiveChannel
	}

	clientStop := !prod.IsServer && stopSession

	if clientStop {
		if ch.ServiceStatus == data.ServiceTerminated {
			logger.Warn("already terminated channel")
			return nil
		}

		status := data.ServiceSuspended
		if ch.ServiceStatus == data.ServiceTerminating {
			status = data.ServiceTerminated
		}

		err := job.AddWithData(h.queue, nil,
			data.JobClientCompleteServiceTransition,
			data.JobChannel, ch.ID, data.JobSessionServer,
			status)
		if err != nil && err != job.ErrDuplicatedJob {
			logger.Error(err.Error())
			return err
		}
	}

	sess, err := h.findCurrentSession(logger, ch.ID)
	if err != nil {
		
		
		if err == ErrSessionNotFound && clientStop {
			return nil
		}
		return err
	}
	logger = logger.Add("session", sess)

	if units != 0 {
		
		units /= 1024 * 1024

		switch prod.UsageRepType {
		case data.ProductUsageIncremental:
			sess.UnitsUsed += units
		case data.ProductUsageTotal:
			sess.UnitsUsed = units
		default:
			logger.Fatal("unsupported product usage")
		}
	}

	sess.LastUsageTime = time.Now()
	if stopSession {
		sess.Stopped = pointer.ToTime(sess.LastUsageTime)
	}

	logger.Info("updating session")

	if err := h.db.Save(sess); err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	return nil
}
func ( h * Handler ) UpdateSession ( product , productPassword , clientKey string , units uint64 , stopSession bool ) error { logger := h . logger . Add ( " " , " " , " " , product , " " , clientKey , " " , units , " " , stopSession ) if stopSession { logger . Info ( " " ) } else { logger . Info ( " " ) } prod , err := h . checkProductPassword ( logger , product , productPassword ) if err != nil { return err } ch , err := h . findClientChannel ( logger , prod , clientKey , true ) if err != nil { return err } // Make the server adapter to kill the session for non-active channel. if prod . IsServer && ch . ServiceStatus != data . ServiceActive { logger . Warn ( " " ) return ErrNonActiveChannel } clientStop := ! prod . IsServer && stopSession if clientStop { if ch . ServiceStatus == data . ServiceTerminated { logger . Warn ( " " ) return nil } status := data . ServiceSuspended if ch . ServiceStatus == data . ServiceTerminating { status = data . ServiceTerminated } err := job . AddWithData ( h . queue , nil , data . JobClientCompleteServiceTransition , data . JobChannel , ch . ID , data . JobSessionServer , status ) if err != nil && err != job . ErrDuplicatedJob { logger . Error ( err . Error ( ) ) return err } } sess , err := h . findCurrentSession ( logger , ch . ID ) if err != nil { // Client adapter can signal failure immediately, when no // session is yet created. if err == ErrSessionNotFound && clientStop { return nil } return err } logger = logger . Add ( " " , sess ) if units != 0 { // TODO: Use unit size instead of this hardcode. units /= 1024 * 1024 switch prod . UsageRepType { case data . ProductUsageIncremental : sess . UnitsUsed += units case data . ProductUsageTotal : sess . UnitsUsed = units default : logger . Fatal ( " " ) } } sess . LastUsageTime = time . Now ( ) if stopSession { sess . Stopped = pointer . ToTime ( sess . LastUsageTime ) } logger . Info ( " " ) if err := h . db . Save ( sess ) ; err != nil { logger . Error ( err . Error ( ) ) return ErrInternal } return nil }
// UpdateSession updates and optionally stops the current client session.
UpdateSession updates and optionally stops the current client session .