github.com/christoph-karpowicz/db_mediator@v0.0.0-20210207102849-61a28a1071d8/internal/server/application/application.go (about)

     1  /*
     2  Package application handles all initializations and
     3  I/O of the app.
     4  */
     5  package application
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"net/http"
    11  	"time"
    12  
    13  	"github.com/christoph-karpowicz/db_mediator/internal/server/db"
    14  	synchPkg "github.com/christoph-karpowicz/db_mediator/internal/server/synch"
    15  )
    16  
    17  /*
    18  Application is the main app object.
    19  Contains all synchronization and database objects.
    20  Starts a web server and handles all requests.
    21  */
    22  type Application struct {
    23  	dbs    db.Databases
    24  	synchs synchPkg.Synchs
    25  }
    26  
    27  // Init starts the application.
    28  func (a *Application) Init() {
    29  	a.dbs = make(db.Databases)
    30  	a.dbs.Init()
    31  	a.synchs = synchPkg.CreateSynchs()
    32  	a.synchs.Init()
    33  	a.listen()
    34  }
    35  
    36  func (a *Application) listen() {
    37  	http.Handle("/", &frontHandler{app: a})
    38  	http.Handle("/ws/", &webSocketHandler{app: a})
    39  	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("front/build/static"))))
    40  	http.Handle("/runSynch", &runSynchHandler{app: a})
    41  	http.Handle("/stopSynch", &stopSynchHandler{app: a})
    42  	http.ListenAndServe(":8000", nil)
    43  }
    44  
    45  // runSynch carries out a synchronization run requested by the client.
    46  func (a *Application) runSynch(responseChan chan *response, synchType string, synchName string, isSimulation bool) {
    47  	defer func() {
    48  		if r := recover(); r != nil {
    49  			responseChan <- createResponse(r.(error))
    50  		}
    51  	}()
    52  
    53  	synch, synchFound := a.synchs[synchName]
    54  	if !synchFound {
    55  		panic("[synchronization search] '" + synchName + "' not found.")
    56  	}
    57  
    58  	synch.SetSimulation(isSimulation)
    59  
    60  	// Initialize synchronization.
    61  	synchID := synch.Init(a.dbs, synchType)
    62  
    63  	// Carry out all synch actions.
    64  	if !isSimulation && synch.GetType() == synchPkg.ONGOING {
    65  		go a.runSynchLoop(synch)
    66  		responseChan <- createResponse(fmt.Sprintf("Synch %s started with ID %s.", synchName, synchID))
    67  	} else {
    68  		synch.Run()
    69  		synchResponse := synch.Flush()
    70  		responseChan <- createResponse(synchResponse)
    71  		synch.Reset()
    72  	}
    73  }
    74  
    75  func (a *Application) runSynchLoop(synch *synchPkg.Synch) {
    76  	for synch.IsInitial() || synch.IsRunning() {
    77  		fmt.Println("run synch")
    78  		synch.Run()
    79  		synch.SetInitial(false)
    80  		time.Sleep(1 * time.Second)
    81  	}
    82  }
    83  
    84  // stopSynch stops a specified synchronization.
    85  func (a *Application) stopSynch(responseChan chan *response, synchName string) {
    86  	defer func() {
    87  		if r := recover(); r != nil {
    88  			responseChan <- createResponse(r.(error))
    89  		}
    90  	}()
    91  
    92  	var synchResponse interface{}
    93  	synch, synchFound := a.synchs[synchName]
    94  	if !synchFound {
    95  		synchResponse = fmt.Sprintf("[synchronization search] \"%s\" not found.", synchName)
    96  	} else if synch.IsRunning() {
    97  		synch.Stop()
    98  		synchResponse = synch.Flush()
    99  		synch.Reset()
   100  	} else {
   101  		synchResponse = fmt.Sprintf("Synch \"%s\" is not running.", synchName)
   102  	}
   103  
   104  	fmt.Println(synchResponse)
   105  	// Send the reponse to the http init handler.
   106  	responseChan <- createResponse(synchResponse)
   107  }
   108  
   109  func (a *Application) listSynchs() []string {
   110  	synchList := make([]string, 0)
   111  	for name := range a.synchs {
   112  		synchList = append(synchList, name)
   113  	}
   114  	return synchList
   115  }
   116  
   117  func (a *Application) listSynchsToJSON() []byte {
   118  	synchList := a.listSynchs()
   119  	synchListJSON, err := json.Marshal(synchList)
   120  	if err != nil {
   121  		panic(err)
   122  	}
   123  	return synchListJSON
   124  }