I start to get acquainted with goLang, a question arose. How to make synchronous requests, by analogy of how they work in PHP with the included recording in the session? So that when sending several AJAX requests at once, they were given in turn. As I understand it, you need to start each request in a stream and give a response after the thread has completed. For how many threads you can count on a weak server with about 256MB of RAM

So that instead of such a picture http://screencloud.net/v/zo92

There was such http://screencloud.net/v/uO7E

    2 answers 2

    For one session, requests are processed strictly sequentially - you need to independently make a synchronization mechanism and process braking.

    for example

    var( SessionsMapMutex Mutex SessionsMap map[string]*Mutex ) ... func RequestWorker(session_id string){ var mutex *Mutex var ok bool SessionsMapMutex.Lock() if mutex, ok = SessionsMap[session_id]; !ok { mutex = &Mutex{} SessionsMap[session_id] = mutex } SessionsMapMutex.Unlock() mutex.Lock() defer mutex.Unlock() Work... } 

    The number of simultaneous requests depends on their resource intensity. For example, if each request for a gigabyte of memory requires and you will store all this in memory - not even one is enough.

    By the number of gorutin (the number of pending requests), as far as I know there are no special restrictions - also until the memory runs out. Each gorutina will take several kilobytes on itself.

      In golang there are such entities as channel. They do an excellent job (actually, for this purpose, they were invented) with the organization of synchronous processing of client requests. You create a channel and write any incoming request to it (before or after logic) and write one function that reads channel from this and you can be sure that the client will see the answers in the sequence in which the server processed them.

       func createChannel(){ c = make(chan byte) } func httpRequestHandler(requestMsg []byte){ if resJson := getResut(requestMsg); res != nil{ c <- resJson } } func sendReplyToClient(){ for{ select{ case reply, ok := <- c: if !ok{ errorhandling() return } sendReplyMsgToClient(reply) case err, ok := <- errChannel: if !ok{ errorhandling() return } sendErrorMsgToClient(reply) } } } 

      The cycle will skip through the channels and as soon as a message appears in the channel, pull it out of the channel and start the handler from the case. The channel is a banal line-up with several fascinating features. Very handy thing.