timer.go raw

   1  // Copyright 2022-2025 The sacloud/iaas-api-go Authors
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //      http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  package fake
  16  
  17  import (
  18  	"fmt"
  19  	"time"
  20  
  21  	"github.com/sacloud/iaas-api-go/accessor"
  22  	"github.com/sacloud/iaas-api-go/types"
  23  )
  24  
  25  var (
  26  	// DiskCopyDuration ディスクコピー処理のtickerで利用するduration
  27  	DiskCopyDuration = 10 * time.Millisecond
  28  	// PowerOnDuration 電源On処理のtickerで利用するduration
  29  	PowerOnDuration = 10 * time.Millisecond
  30  	// PowerOffDuration 電源Off処理のtickerで利用するduration
  31  	PowerOffDuration = 10 * time.Millisecond
  32  )
  33  
  34  func startDiskCopy(resourceKey, zone string, readFunc func() (interface{}, error)) {
  35  	counter := 0
  36  	ticker := time.NewTicker(DiskCopyDuration)
  37  	go func() {
  38  		defer ticker.Stop()
  39  		for {
  40  			<-ticker.C
  41  
  42  			raw, err := readFunc()
  43  			if raw == nil || err != nil {
  44  				return
  45  			}
  46  			target, ok := raw.(accessor.DiskMigratable)
  47  			if !ok {
  48  				return
  49  			}
  50  
  51  			if counter < 3 {
  52  				target.SetAvailability(types.Availabilities.Migrating)
  53  				if counter == 0 {
  54  					target.SetMigratedMB(0)
  55  				} else {
  56  					target.SetMigratedMB(target.GetSizeMB() / counter)
  57  				}
  58  			} else {
  59  				target.SetAvailability(types.Availabilities.Available)
  60  				target.SetMigratedMB(target.GetSizeMB())
  61  				ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
  62  				return
  63  			}
  64  			ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
  65  			counter++
  66  		}
  67  	}()
  68  }
  69  
  70  func startMigration(resourceKey, zone string, readFunc func() (interface{}, error)) {
  71  	counter := 0
  72  	ticker := time.NewTicker(DiskCopyDuration)
  73  	go func() {
  74  		defer ticker.Stop()
  75  		for {
  76  			<-ticker.C
  77  
  78  			raw, err := readFunc()
  79  			if raw == nil || err != nil {
  80  				return
  81  			}
  82  			target, ok := raw.(accessor.Availability)
  83  			if !ok {
  84  				return
  85  			}
  86  
  87  			if counter < 3 {
  88  				target.SetAvailability(types.Availabilities.Migrating)
  89  			} else {
  90  				target.SetAvailability(types.Availabilities.Available)
  91  				ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
  92  				return
  93  			}
  94  			ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
  95  			counter++
  96  		}
  97  	}()
  98  }
  99  
 100  func startPowerOn(resourceKey, zone string, readFunc func() (interface{}, error)) {
 101  	counter := 0
 102  	ticker := time.NewTicker(PowerOnDuration)
 103  	go func() {
 104  		defer ticker.Stop()
 105  		for {
 106  			<-ticker.C
 107  
 108  			raw, err := readFunc()
 109  			if raw == nil || err != nil {
 110  				return
 111  			}
 112  			target, ok := raw.(accessor.InstanceStatus)
 113  			if !ok {
 114  				return
 115  			}
 116  
 117  			if counter < 3 {
 118  				target.SetInstanceStatus(types.ServerInstanceStatuses.Down)
 119  			} else {
 120  				target.SetInstanceStatus(types.ServerInstanceStatuses.Up)
 121  				if status, ok := target.(accessor.Instance); ok {
 122  					status.SetInstanceHostName(fmt.Sprintf("sac-%s-svXXX", zone))
 123  					status.SetInstanceHostInfoURL("")
 124  					status.SetInstanceStatusChangedAt(time.Now())
 125  				}
 126  				if available, ok := target.(accessor.Availability); ok {
 127  					available.SetAvailability(types.Availabilities.Available)
 128  				}
 129  				ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
 130  				return
 131  			}
 132  			ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
 133  			counter++
 134  		}
 135  	}()
 136  }
 137  
 138  func startPowerOff(resourceKey, zone string, readFunc func() (interface{}, error)) {
 139  	counter := 0
 140  	ticker := time.NewTicker(PowerOffDuration)
 141  	go func() {
 142  		defer ticker.Stop()
 143  		for {
 144  			<-ticker.C
 145  
 146  			raw, err := readFunc()
 147  			if raw == nil || err != nil {
 148  				return
 149  			}
 150  			target, ok := raw.(accessor.InstanceStatus)
 151  			if !ok {
 152  				return
 153  			}
 154  
 155  			if status, ok := target.(accessor.Instance); ok {
 156  				status.SetInstanceHostName(fmt.Sprintf("sac-%s-svXXX", zone))
 157  				status.SetInstanceHostInfoURL("")
 158  				status.SetInstanceStatusChangedAt(time.Now())
 159  			}
 160  
 161  			if counter < 3 {
 162  				target.SetInstanceStatus(types.ServerInstanceStatuses.Cleaning)
 163  			} else {
 164  				target.SetInstanceStatus(types.ServerInstanceStatuses.Down)
 165  				ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
 166  				return
 167  			}
 168  
 169  			ds().Put(resourceKey, zone, target.(accessor.ID).GetID(), target)
 170  			counter++
 171  		}
 172  	}()
 173  }
 174