[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Brian Candler
At the start of the thread, you said "if I compile and run this simple 
program ..."

Does the problem no longer reproduce with that?

On Monday, 11 April 2022 at 22:59:55 UTC+1 scorr...@gmail.com wrote:

> I tried with a more complex application and already got constant 100% CPU 
> usage twice. 
>
> When I attach strace I see the same as with the minimal demo but with much 
> more frecuency:
>
> [pid 42659] 23:36:49.035120 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035133 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035145 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035158 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035170 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035182 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035195 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035207 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035219 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035232 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035244 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035257 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035269 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035281 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
> [pid 42659] 23:36:49.035293 epoll_pwait(3, [], 128, 0, NULL, 
> 140341803388040) = 0
> [pid 42659] 23:36:49.035306 epoll_pwait(3, [], 128, 0, NULL, 
> 18704162493558) = 0
>
> The program is too large to post here. I have tested it with go race and 
> it doesn't run into any problem. Any idea of what to look for?
>
> Thank you!
>
> El lunes, 11 de abril de 2022 a las 17:08:40 UTC+2, Santiago Corredoira 
> escribió:
>
>> I tried with the stripped tmp version of "go run" and after a while I was 
>> able to reproduce it too. It definitely took me more time but probably is 
>> just random. 
>>
>> I tried "$ GODEBUG=asyncpreemptoff=1 ./test" and I kept seeing the the 
>> calls every 10ms. Is this expected to happen?
>>
>> I compiled the test with "$ go1.16 build test.go" and I tried hard to 
>> reproduce it but I couldn't. It is very strange because this behaviour was 
>> introduced in Go 1.14 and I only see it in Go 1.17. Also asyncpreemptoff=1 
>> seems to make no difference.
>>
>> I am going to work again with Go 1.18 by default to see if I get the 100% 
>> CPU usage.
>>
>> El lunes, 11 de abril de 2022 a las 13:28:48 UTC+2, Brian Candler 
>> escribió:
>>
>>> On Monday, 11 April 2022 at 09:26:28 UTC+1 scorr...@gmail.com wrote:
>>>
 and the output keeps growing like that with every new curl request 
 until eventually it starts constantly printing output like this:

>
> [pid 143818] 10:02:22.697120 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.707609 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.718125 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.728753 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.739195 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.749618 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.760160 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.770669 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.781137 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.791581 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.802060 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.812540 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.822981 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
> [pid 143818] 10:02:22.833468 nanosleep({tv_sec=0, tv_nsec=1000}, 
> NULL) = 0
>
>
>>> That is normal, I believe, for a process with multiple runnable 
>>> goroutines - one alarm/wakeup call every 10ms.
>>>
>>> What is odd is the 100% CPU utilisation.  Can you attach an strace when 
>>> that happens?
>>>
>>> As for the binary produced by "go run" - use "ps" to see where it is.  
>>> For example:
>>>
>>> ==> sleepy.go <==
>>> package main
>>>
>>> import (
>>> "sync"
>>> "time"
>>> )
>>>
>>> func main() {
>>> var wg sync.WaitGroup
>>> wg.Add(1)
>>> go func() {
>>> time.Sleep(30 * time.Second)
>>> wg.Done()
>>> }()
>>> wg.Wait()
>>> }
>>> ==> end <==
>>>
>>> $ go run sleepy.go
>>>
>>> ... in

[go-nuts] Why Go has only slice and map

2022-04-11 Thread 'Jack Li' via golang-nuts
Hi group,


Why Go provides only 2 built-in data structures, slice and map. It has just 
more than C, but less than all other programming languages I've heard of, C++, 
Python, Swift, Rust. 


I think this simplicity attracts me very much. Sometimes I can use only one 
data structures for a task. Because there is no more similar data 
structures for choice. It's really "one way to do one thing". This also makes 
code like familiar and consistent.


I want to know more about the mind behind this design of built-in data 
structures.



Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/tencent_7D168C1B263BF2B862B18796F28F82753009%40qq.com.


Re: [go-nuts] Hesitating on using cached / un-cached channels

2022-04-11 Thread burak serdar
An unbuffered channel is a synchronization mechanism. A send on an
unbuffered channel will block until there is a concurrent receive from
another goroutine.

Your program has only one goroutine. A send to an unbuffered channel will
always deadlock, so will a receive from it. So the problem you are
describing is not a problem related to the way unbuffered channels work,
but it is due to the way the program is organized: it is written to
deadlock. With a buffered channel, it can run. This program does not need a
buffer more than 1. Once the send runs, the channel will be full, and the
second case will be activated. The first case cannot run until the second
case is done, which will terminate the loop.

On Mon, Apr 11, 2022 at 10:08 PM robert engels 
wrote:

> There are numerous ways to create a “dead lock” in any program (this may
> actually be a “live lock” but I didn’t fully understand your statement -
> this is just one of them.
>
>
> On Apr 11, 2022, at 9:29 PM, Zhaoxun Yan  wrote:
>
> Hi guys, I have a great demonstration on why an un-cached channel might
> malfunction while receiving:
>
> package main
> import(
> "fmt"
> "time"
> )
>
> func main(){
> t := time.NewTicker(time.Second * 3)
> stopnow := make(chan bool)
> //stopnow := make(chan bool, 1) //cached channel instead
> var n int
>
> for{
> select{
> case <-t.C:
> n++
> fmt.Printf("%d\n", n)
>
> if n==3{
> stopnow <- true //The Only Sending!!!
> t.Stop()
> }
>
> case a:=<-stopnow: //The Only Receiving!!!
> if a{
> goto END
> }
> }
> }
> END:
> fmt.Println("out of select")
> }
>
> In the code above, you will never see the printout "out of select" ,
> because the for-select receiver is not working while the code is run inside
> timer receiver in the line " stopnow <- true".
>
> So an un-cached channel like " stopnow := make(chan bool)" will
> occasionally but inevitably miss receiving while the code is busy
> processing a competing receiving.
>
> That is why I use cached channel instead, like " stopnow := make(chan
> bool, 1)", which un-received message(s) will be cached until gotten
> received.
>
> However there comes another vulnerability - How large should the cache be?
>
> In a simple scenario like this, I am very confident there will be 1
> message to receive only. But on a complex server, it is very common that a
> goroutine will receive unexpected many messages from other goroutine or
> functions. And it is not safe for the programmer to just guess a ceiling
> for the number of unprocessed messages on any time - just as to guess the
> maximum on how many cars can line up after a red light. If you guess wrong,
> only one additional message will breach the cache and cause a crash:
>
> package main
>
> var c = make(chan int, 1)
>
> func main() {
>
> c <- 1
> c <- 2 //fatal error: all goroutines are asleep - deadlock!
> c <- 3
>
> }
>
> The code above crashes at the point that the cache of channel c is full,
> but the sender still puts another message into it.
>
> What is your thought on this?
> Regards,
> Zhaoxun
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fefc350d-3423-4fb6-b844-703ce03c7e5fn%40googlegroups.com
> 
> .
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/FD201AFD-CD9D-48A8-AD3D-3B1813F3A479%40ix.netcom.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpqNZKYC5a1JOzue1PkW9RhB3aL6n6z3Gsm-ifoCTQ%3DFQ%40mail.gmail.com.


Re: [go-nuts] Hesitating on using cached / un-cached channels

2022-04-11 Thread robert engels
There are numerous ways to create a “dead lock” in any program (this may 
actually be a “live lock” but I didn’t fully understand your statement - this 
is just one of them. 


> On Apr 11, 2022, at 9:29 PM, Zhaoxun Yan  wrote:
> 
> Hi guys, I have a great demonstration on why an un-cached channel might 
> malfunction while receiving:
> 
> package main
> import(
> "fmt"
> "time"
> ) 
> 
> func main(){
> t := time.NewTicker(time.Second * 3)
> stopnow := make(chan bool)
> //stopnow := make(chan bool, 1) //cached channel instead
> var n int
> 
> for{
> select{
> case <-t.C:
> n++
> fmt.Printf("%d\n", n)
> 
> if n==3{
> stopnow <- true //The Only Sending!!!
> t.Stop()
> }
> 
> case a:=<-stopnow: //The Only Receiving!!!
> if a{
> goto END
> }
> }
> }
> END:
> fmt.Println("out of select")
> }
> 
> In the code above, you will never see the printout "out of select" , because 
> the for-select receiver is not working while the code is run inside timer 
> receiver in the line " stopnow <- true".
> 
> So an un-cached channel like " stopnow := make(chan bool)" will occasionally 
> but inevitably miss receiving while the code is busy processing a competing 
> receiving.
> 
> That is why I use cached channel instead, like " stopnow := make(chan bool, 
> 1)", which un-received message(s) will be cached until gotten received.
> 
> However there comes another vulnerability - How large should the cache be?
> 
> In a simple scenario like this, I am very confident there will be 1 message 
> to receive only. But on a complex server, it is very common that a goroutine 
> will receive unexpected many messages from other goroutine or functions. And 
> it is not safe for the programmer to just guess a ceiling for the number of 
> unprocessed messages on any time - just as to guess the maximum on how many 
> cars can line up after a red light. If you guess wrong, only one additional 
> message will breach the cache and cause a crash:
> 
> package main
> 
> var c = make(chan int, 1)
> 
> func main() {
> 
> c <- 1
> c <- 2 //fatal error: all goroutines are asleep - deadlock!
> c <- 3
> 
> } 
> 
> The code above crashes at the point that the cache of channel c is full, but 
> the sender still puts another message into it.
> 
> What is your thought on this?
> Regards,
> Zhaoxun
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/fefc350d-3423-4fb6-b844-703ce03c7e5fn%40googlegroups.com
>  
> .

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/FD201AFD-CD9D-48A8-AD3D-3B1813F3A479%40ix.netcom.com.


[go-nuts] Re: Is it possible to change the existing printline dynamically in golang?

2022-04-11 Thread Zhaoxun Yan
Thanks a log Amnon! :D

在2022年4月1日星期五 UTC+8 21:25:14 写道:

> Yes, this is the murky world of ANSI escape codes.
> Fortunately there are a whole load of libraries which do this for you...
> Try https://github.com/cheggaaa/pb
> or https://github.com/schollz/progressbar
> or github.com/vardius/progress-go
>
>
> On Friday, 1 April 2022 at 13:12:11 UTC+1 yan.z...@gmail.com wrote:
>
>> Got it:
>>
>> package main
>>
>> import(
>> "fmt"
>> "time"
>> )
>>
>> func main() {
>>   fmt.Printf("Hello")
>>   time.Sleep(time.Second)
>>   time.Sleep(time.Second)
>>   fmt.Printf("\r")
>>   fmt.Printf("World\n")
>> }
>>
>> 在2022年4月1日星期五 UTC+8 15:34:08 写道:
>>
>>> You can use the ansi escape code if the target terminal supports it. 
>>> Alternatively, you can use the carriage return '\r' and reprint the line. 
>>> Note you may need to overwrite with empty space to delete the line before 
>>> rewriting it.
>>>
>>> On Friday, April 1, 2022 at 12:38:37 PM UTC+7 yan.z...@gmail.com wrote:
>>>
 I just noticed how python pip upgraded from printing numerous process 
 bars like this:
 ■■■   30% completed
  40% completed
 ■■60% completed
    80% completed
 ■■  100% completed

 to a single line of a growing bar and changing declaration.

 It is definitely a functionality that  prompts of both Linux and 
 Windows allows -
 To change the previous print line.
 Is it possible to realize this in golang?

   Zhaoxun

>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/cb9fdc0b-fc25-4b7b-b53b-1377f906829dn%40googlegroups.com.


[go-nuts] encoding/json mistakenly transfer int64 format to string

2022-04-11 Thread Zhaoxun Yan
The scenario is upon receiving an incoming financial quotation, save it as 
a string of json into a Redis service. Sorry but I cannot provide the whole 
code of quotation receiving here, which is very complex with cgo. But the 
code below will help you get a glimpse on what should be going on:

import (
"encoding/json"
//"errors"
"fmt"
"time"

"github.com/garyburd/redigo/redis"
)

var pool *redis.Pool

type Fvprices struct {
P float64 `json:"price"`
F float64 `json:"floor"`
C float64 `json:"ceiling"`
S float64 `json:"settle"`
T int64   `json:"time"`
}

func init() {
pool = newPool()
}

var redisport = "6379"
var redisip = "127.0.0.1"
var password = ""

func newPool() *redis.Pool {

fmt.Println("redis @", redisport, redisip, password)
return &redis.Pool{ 
MaxIdle: 4,
MaxActive:   50, // max number of connections
IdleTimeout: 30 * time.Second,

Dial: func() (redis.Conn, error) {
c, err := redis.DialURL("redis://" + redisip + ":" + redisport)
if err != nil {
ErrMsg = fmt.Sprintf("redis connection error: %s", err.Error
())
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), 
ErrMsg)
return nil, err
}
if _, autherr := c.Do("AUTH", password); autherr != nil {
ErrMsg = fmt.Sprintf("redis password error: %s", err.Error
())
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), 
ErrMsg)
return nil, autherr
}
return c, nil
},
}
}

func Upfutureprice(future_id string,
future_price, lowerLimitPrice, upperLimitPrice, preSettlementPrice 
float64,
updatetime time.Time) {

c := pool.Get()
if c == nil {
return
}
defer c.Close()

content := Fvprices{
P: future_price,
F: lowerLimitPrice,
C: upperLimitPrice,
S: preSettlementPrice,
T: updatetime.UnixNano() / 1e6,
}

js, _ := json.Marshal(content)

if _, err := c.Do("SET", future_id, js); err != nil {
fmt.Println("cannot save to redis:", err)
}
}

So obviously until the function "Upfutureprice" everything is correct, for 
all  four prices it receives are in float64 format. After running this 
program for one day, I just browse the redis using 
AnotherRedisDesktopManager via ssh port forwarding, and something strange 
happens as I clicking on various future_id key strings:

{
price:807
floor:720.6
ceiling:881
settle:"800.80001"
time:1649726499000
}

{
price:"3691.5"
floor:3237
ceiling:4204
settle:3721
time:1649726910500
}

{
price:"15405.0004"
floor:13625
ceiling:17340
settle:15485
time:1649728303500
}

{
price:"800.40001"
floor:720.6
ceiling:881
settle:"800.80001"
time:1649728048000
}

Note quotations above. I wonder how encoding/json can made transformation 
from a float64 inside struct Fvprices  to a string instead? It seems that 
only long decimals would trigger such an error while short decimals won't:

{
price:2910
floor:2443.5
ceiling:3305.5
settle:2874.5
time:1649728261026
}

How could that happen? I am really puzzled.

Regards,
Zhaoxun

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f42b29b3-de17-48c6-9f71-1176f1288396n%40googlegroups.com.


[go-nuts] Hesitating on using cached / un-cached channels

2022-04-11 Thread Zhaoxun Yan
Hi guys, I have a great demonstration on why an un-cached channel might 
malfunction while receiving:

package main
import(
"fmt"
"time"
) 

func main(){
t := time.NewTicker(time.Second * 3)
stopnow := make(chan bool) 
//stopnow := make(chan bool, 1) //cached channel instead
var n int

for{
select{
case <-t.C:
n++
fmt.Printf("%d\n", n)

if n==3{
stopnow <- true //The Only Sending!!!
t.Stop()
}

case a:=<-stopnow: //The Only Receiving!!!
if a{
goto END
}
}
}
END:
fmt.Println("out of select")
}

In the code above, you will never see the printout "out of select" , 
because the for-select receiver is not working while the code is run inside 
timer receiver in the line " stopnow <- true".

So an un-cached channel like " stopnow := make(chan bool)" will 
occasionally but inevitably miss receiving while the code is busy 
processing a competing receiving.

That is why I use cached channel instead, like " stopnow := make(chan bool, 
1)", which un-received message(s) will be cached until gotten received.

However there comes another vulnerability - How large should the cache be?

In a simple scenario like this, I am very confident there will be 1 message 
to receive only. But on a complex server, it is very common that a 
goroutine will receive unexpected many messages from other goroutine or 
functions. And it is not safe for the programmer to just guess a ceiling 
for the number of unprocessed messages on any time - just as to guess the 
maximum on how many cars can line up after a red light. If you guess wrong, 
only one additional message will breach the cache and cause a crash:

package main

var c = make(chan int, 1)

func main() {

c <- 1
c <- 2 //fatal error: all goroutines are asleep - deadlock!
c <- 3

} 

The code above crashes at the point that the cache of channel c is full, 
but the sender still puts another message into it.

What is your thought on this?
Regards,
Zhaoxun

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/fefc350d-3423-4fb6-b844-703ce03c7e5fn%40googlegroups.com.


Re: [go-nuts] why the opendefer optimization will close when my function's named return value escape

2022-04-11 Thread Ian Lance Taylor
On Thu, Apr 7, 2022 at 11:03 AM ワタナベハルキ  wrote:
>
> GOARCH="amd64"
> GOHOSTOS="linux"
> GOVERSION="go1.17.2"
>
> Here is my test code
>
> var sink *int
>
> func main(){
> escape()
> }
>
> // named return value r
> func escape() (r int) {
> defer func(){
> recover()
> }()
> sink = &r // escape r
> panic("qOeOp")
> return
> }
>
> jokoi@ubuntu:~/GoProJ/test$ go build -gcflags "-d defer" main.go
> ./main.go:11:2: stack-allocated defer
>
> and i find something comment may be useful in package 
> cmd/compile/internel/ssagen
>
> if s.hasOpenDefers {
> ..
> // Similarly, skip if there are any heap-allocated result
> // parameters that need to be copied back to their stack 
> slots.
> for _, f := range s.curfn.Type().Results().FieldSlice() {
> if !f.Nname.(*ir.Name).OnStack() {
> s.hasOpenDefers = false
> break
> }
> }
> }
> ..
> }
>
> but i cannot understand why ? As far as i know , coping heap-allocated result 
> parameter back just need a small piece of code like mov rax [rax] at the exit 
> point of one function , why compiler cannot generate  it .

It was probably just never implemented.  An escaping result parameter
is not a common case.

I expect the compiler developers would be happy to review a patch that
makes it work.  See https://go.dev/doc/contribute.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUOyUaA0ZyYOpPsDdPg%2B0Y8o9Jk0a9HSvwxA_RxoCU%2BpQ%40mail.gmail.com.


Re: [go-nuts] Why does infinitely-recursing code not give stack overflow in Playground?

2022-04-11 Thread Sam Hughes
I've hit this problems a few times, and I immediately thumbs-upped that 
issue report.

To correct @Ben, I suggest the purest reasoning for an error being 
displayed is "The process completed, and did not succeed". In your case, 
@Ben, yeah, it was killed while waiting on something, but the normal case 
is when I kick off an A/B test with too many iterations, or that is 
particularly heavy. It's easy enough to do an A/B test locally, but if 
you're changing someone's snippet and resharing, or else producing the test 
to send to a colleague. It happens seldom enough that I go through the same 
little confusion-frustration-shorten sequence whenever this happens.

If the process got killed, whatever it's running on, it's worth notifying 
the remote (us) that it had to be killed, even if it doesn't include a 
stack-trace. 

On Monday, April 11, 2022 at 5:04:21 PM UTC-5 ben...@gmail.com wrote:

> Depending on implementation, infinite recursion is not guaranteed to blow 
>> the stack for the program given. The function call is in tail position, so 
>> a tail-call optimization (TCO) pass would be able to rewrite the program 
>> into an infinite loop by reusing the existing stack frame for each 
>> invocation of f[0].
>>
>
> Understood. But I think there are two reasons this code in the playground 
> should still show an error:
>
> 1) The existing Go compilers don't do tail-call optimization, so keeping 
> the discussion real and concrete, they will overflow the stack.
> 2) Even if they did implement tail-call optimization, this would be an 
> infinite loop, so it should show a timeout error, like an infinite for loop 
> does: https://go.dev/play/p/GH67vNtpZyp
>
> -Ben
>  
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/330aa6aa-d975-422d-8405-a261b5fd3b1an%40googlegroups.com.


Re: [go-nuts] Why does infinitely-recursing code not give stack overflow in Playground?

2022-04-11 Thread ben...@gmail.com


> Depending on implementation, infinite recursion is not guaranteed to blow 
> the stack for the program given. The function call is in tail position, so 
> a tail-call optimization (TCO) pass would be able to rewrite the program 
> into an infinite loop by reusing the existing stack frame for each 
> invocation of f[0].
>

Understood. But I think there are two reasons this code in the playground 
should still show an error:

1) The existing Go compilers don't do tail-call optimization, so keeping 
the discussion real and concrete, they will overflow the stack.
2) Even if they did implement tail-call optimization, this would be an 
infinite loop, so it should show a timeout error, like an infinite for loop 
does: https://go.dev/play/p/GH67vNtpZyp

-Ben
 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/e4822715-caab-40b5-a345-9f5604e248cfn%40googlegroups.com.


[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Santiago Corredoira
I tried with a more complex application and already got constant 100% CPU 
usage twice. 

When I attach strace I see the same as with the minimal demo but with much 
more frecuency:

[pid 42659] 23:36:49.035120 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035133 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035145 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035158 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035170 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035182 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035195 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035207 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035219 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035232 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035244 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035257 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035269 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035281 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0
[pid 42659] 23:36:49.035293 epoll_pwait(3, [], 128, 0, NULL, 
140341803388040) = 0
[pid 42659] 23:36:49.035306 epoll_pwait(3, [], 128, 0, NULL, 
18704162493558) = 0

The program is too large to post here. I have tested it with go race and it 
doesn't run into any problem. Any idea of what to look for?

Thank you!

El lunes, 11 de abril de 2022 a las 17:08:40 UTC+2, Santiago Corredoira 
escribió:

> I tried with the stripped tmp version of "go run" and after a while I was 
> able to reproduce it too. It definitely took me more time but probably is 
> just random. 
>
> I tried "$ GODEBUG=asyncpreemptoff=1 ./test" and I kept seeing the the 
> calls every 10ms. Is this expected to happen?
>
> I compiled the test with "$ go1.16 build test.go" and I tried hard to 
> reproduce it but I couldn't. It is very strange because this behaviour was 
> introduced in Go 1.14 and I only see it in Go 1.17. Also asyncpreemptoff=1 
> seems to make no difference.
>
> I am going to work again with Go 1.18 by default to see if I get the 100% 
> CPU usage.
>
> El lunes, 11 de abril de 2022 a las 13:28:48 UTC+2, Brian Candler escribió:
>
>> On Monday, 11 April 2022 at 09:26:28 UTC+1 scorr...@gmail.com wrote:
>>
>>> and the output keeps growing like that with every new curl request until 
>>> eventually it starts constantly printing output like this:
>>>

 [pid 143818] 10:02:22.697120 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.707609 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.718125 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.728753 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.739195 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.749618 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.760160 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.770669 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.781137 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.791581 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.802060 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.812540 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.822981 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0
 [pid 143818] 10:02:22.833468 nanosleep({tv_sec=0, tv_nsec=1000}, 
 NULL) = 0


>> That is normal, I believe, for a process with multiple runnable 
>> goroutines - one alarm/wakeup call every 10ms.
>>
>> What is odd is the 100% CPU utilisation.  Can you attach an strace when 
>> that happens?
>>
>> As for the binary produced by "go run" - use "ps" to see where it is.  
>> For example:
>>
>> ==> sleepy.go <==
>> package main
>>
>> import (
>> "sync"
>> "time"
>> )
>>
>> func main() {
>> var wg sync.WaitGroup
>> wg.Add(1)
>> go func() {
>> time.Sleep(30 * time.Second)
>> wg.Done()
>> }()
>> wg.Wait()
>> }
>> ==> end <==
>>
>> $ go run sleepy.go
>>
>> ... in another window ...
>> $ ps auxwww | grep sleepy
>> ubuntu 17743  0.0  0.1 1237424 12428 pts/1   Sl+  11:23   0:00 go run 
>> sleepy.go
>> ubuntu 17782  0.0  0.0 702468  1052 pts/1Sl+  11:23   0:00 
>> /tmp/go-build2834561198/b001/exe/sleepy
>>
>> You can 'cp' it somewhere to keep it safe.
>>
>> If I compare this with the output of "go build sleepy.go", I see that th

Re: [go-nuts] Re: [security] Go 1.18.1 and Go 1.17.9 pre-announcement

2022-04-11 Thread Carlos Amedee
Yes, we are still scheduled to release Go 1.18.1 and 1.17.9 on Tuesday 
April 12.

Carlos

On Monday, April 11, 2022 at 3:26:17 PM UTC-4 dav...@gmail.com wrote:

> Carlos, Julie,
>
> Are we still on for tomorrow? (golang 1.18.1 specifically) Please let us 
> know (from k8s side, we are eagerly waiting! [1])
>
> thanks in advance,
> Dims
>
> [1] 
> https://groups.google.com/a/kubernetes.io/g/leads/c/4tFb3pOq3g0/m/payrHytjCgAJ
>
> On Thu, Apr 7, 2022 at 12:12 PM Carlos Amedee  wrote:
>
>> Hello gophers,
>>
>> Due to an issue with release tooling, this release is now planned for 
>> Tuesday, April 12th.
>>
>> Sorry for the inconvenience.
>>
>> Carlos on behalf of the Go team
>> On Monday, April 4, 2022 at 11:25:43 AM UTC-4 Julie Qiu wrote:
>>
>>> Hello gophers,
>>>
>>> We plan to issue Go 1.18.1 and Go 1.17.9 on Thursday, April 7th.
>>>
>>> These minor releases include a PRIVATE security fix to the standard 
>>> library.
>>>
>>> Following our security policy, this is the pre-announcement of those 
>>> releases.
>>>
>>> Thanks,
>>> Julie on behalf of the Go team
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/856fcb34-c7ed-4dca-aab6-c42001492d93n%40googlegroups.com
>>  
>> 
>> .
>>
>
>
> -- 
> Davanum Srinivas :: https://twitter.com/dims
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/453625bc-81c8-4e71-ae35-2d49f219c9dan%40googlegroups.com.


Re: [go-nuts] Re: [security] Go 1.18.1 and Go 1.17.9 pre-announcement

2022-04-11 Thread Davanum Srinivas
Carlos, Julie,

Are we still on for tomorrow? (golang 1.18.1 specifically) Please let us
know (from k8s side, we are eagerly waiting! [1])

thanks in advance,
Dims

[1]
https://groups.google.com/a/kubernetes.io/g/leads/c/4tFb3pOq3g0/m/payrHytjCgAJ

On Thu, Apr 7, 2022 at 12:12 PM Carlos Amedee  wrote:

> Hello gophers,
>
> Due to an issue with release tooling, this release is now planned for
> Tuesday, April 12th.
>
> Sorry for the inconvenience.
>
> Carlos on behalf of the Go team
> On Monday, April 4, 2022 at 11:25:43 AM UTC-4 Julie Qiu wrote:
>
>> Hello gophers,
>>
>> We plan to issue Go 1.18.1 and Go 1.17.9 on Thursday, April 7th.
>>
>> These minor releases include a PRIVATE security fix to the standard
>> library.
>>
>> Following our security policy, this is the pre-announcement of those
>> releases.
>>
>> Thanks,
>> Julie on behalf of the Go team
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/856fcb34-c7ed-4dca-aab6-c42001492d93n%40googlegroups.com
> 
> .
>


-- 
Davanum Srinivas :: https://twitter.com/dims

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANw6fcHPnn96FmqwcMTxoORVFasgDkVvLz%3DJdkMh0YEuM522bQ%40mail.gmail.com.


Re: [go-nuts] Dynamically loading custom passes with gollvm?

2022-04-11 Thread 'Than McIntosh' via golang-nuts
Hello,

At the moment gollvm doesn't support anything like the "-Xclang -load
-Xclang ...".

It would not be too hard to add this though. Want to send a patch?

Thanks, Than


On Sun, Apr 10, 2022 at 3:47 PM Balamurugan Marimuthu 
wrote:

> Yes, something like that! I basically want to run my custom pass as I
> compile using 'go build'
>
>  But looks like llvm-goc doesn't support the -Xclang option
>
>
>
>
> *$ go build -gccgoflags="-Xclang -load -Xclang
> ../passes/FunctionInsertPass.so" cache_main.go#
> command-line-arguments/gollvm/install/bin/llvm-goc: error: unrecognized
> command line option '-Xclang'/gollvm/install/bin/llvm-goc: error:
> unrecognized command line option '-Xclang'*
>
> Is there a way to load my custom pass as part of 'go build'?
>
> Thanks!
>
> On Sunday, April 10, 2022 at 12:14:34 AM UTC-4 Ian Lance Taylor wrote:
>
>> On Sat, Apr 9, 2022 at 8:28 PM Balamurugan Marimuthu
>>  wrote:
>> >
>> > I see I can invoke the following and see the steps 'go build' is doing.
>> >
>> > % go build -work -x mypackage.go 1> transcript.txt 2>&1
>> >
>> > I struggle to understand how can I load my custom pass created as a
>> shared library?
>> >
>> > I was looking for something like this which is done with Clang:
>> > clang -Xclang -load -Xclang build/skeleton/libSkeletonPass.*
>> something.c
>> >
>> > Is my understanding correct? Any help/pointers will be really helpful.
>>
>> Perhaps you are looking for something like
>>
>> go build -gccgoflags="-Xclang -load -Xclang
>> build/skeleton/libSkeletonPass.*"
>>
>> Ian
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/9a976aca-4c5d-4074-a19d-f843e8b5ca63n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2BUr55FHKv3K0rm1S-58Om06_54aj4ZKS8G-nBkgKHVMh6ozrQ%40mail.gmail.com.


Re: [go-nuts] Why does infinitely-recursing code not give stack overflow in Playground?

2022-04-11 Thread Jesper Louis Andersen
On Wed, Apr 6, 2022 at 3:18 AM ben...@gmail.com  wrote:

> Normally the Go Playground gives errors when a runtime panic or other
> error occurs, including "timeout running program" for programs that run too
> long. I'm wondering why the Playground doesn't show a stack overflow error
> (or any error) for this infinitely-recursing program?
>
>
Depending on implementation, infinite recursion is not guaranteed to blow
the stack for the program given. The function call is in tail position, so
a tail-call optimization (TCO) pass would be able to rewrite the program
into an infinite loop by reusing the existing stack frame for each
invocation of f[0].

I don't think the spec explicitly rejects such optimizations, but you can't
rely on TCO either, because it isn't mandated, like it is in e.g., the
specification of the programming language Scheme.

[0] One of the flip sides of such rewriting are that the stack might not
exactly represent the control flow of the program, so in a debugging
situation you have to apply more imagination to figure out what the program
did.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAGrdgiXRx-8dkASeZS5xWohEfgOY8vqCNzSJSgzXyBH9uE6tog%40mail.gmail.com.


[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Santiago Corredoira
I tried with the stripped tmp version of "go run" and after a while I was 
able to reproduce it too. It definitely took me more time but probably is 
just random. 

I tried "$ GODEBUG=asyncpreemptoff=1 ./test" and I kept seeing the the 
calls every 10ms. Is this expected to happen?

I compiled the test with "$ go1.16 build test.go" and I tried hard to 
reproduce it but I couldn't. It is very strange because this behaviour was 
introduced in Go 1.14 and I only see it in Go 1.17. Also asyncpreemptoff=1 
seems to make no difference.

I am going to work again with Go 1.18 by default to see if I get the 100% 
CPU usage.

El lunes, 11 de abril de 2022 a las 13:28:48 UTC+2, Brian Candler escribió:

> On Monday, 11 April 2022 at 09:26:28 UTC+1 scorr...@gmail.com wrote:
>
>> and the output keeps growing like that with every new curl request until 
>> eventually it starts constantly printing output like this:
>>
>>>
>>> [pid 143818] 10:02:22.697120 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.707609 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.718125 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.728753 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.739195 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.749618 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.760160 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.770669 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.781137 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.791581 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.802060 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.812540 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.822981 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>> [pid 143818] 10:02:22.833468 nanosleep({tv_sec=0, tv_nsec=1000}, 
>>> NULL) = 0
>>>
>>>
> That is normal, I believe, for a process with multiple runnable goroutines 
> - one alarm/wakeup call every 10ms.
>
> What is odd is the 100% CPU utilisation.  Can you attach an strace when 
> that happens?
>
> As for the binary produced by "go run" - use "ps" to see where it is.  For 
> example:
>
> ==> sleepy.go <==
> package main
>
> import (
> "sync"
> "time"
> )
>
> func main() {
> var wg sync.WaitGroup
> wg.Add(1)
> go func() {
> time.Sleep(30 * time.Second)
> wg.Done()
> }()
> wg.Wait()
> }
> ==> end <==
>
> $ go run sleepy.go
>
> ... in another window ...
> $ ps auxwww | grep sleepy
> ubuntu 17743  0.0  0.1 1237424 12428 pts/1   Sl+  11:23   0:00 go run 
> sleepy.go
> ubuntu 17782  0.0  0.0 702468  1052 pts/1Sl+  11:23   0:00 
> /tmp/go-build2834561198/b001/exe/sleepy
>
> You can 'cp' it somewhere to keep it safe.
>
> If I compare this with the output of "go build sleepy.go", I see that the 
> "go build" version is larger and unstripped:
>
> $ cp /tmp/go-build2834561198/b001/exe/sleepy sleepy-run
> $ file sleepy-run
> sleepy-run: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
> statically linked, stripped
> $ go build sleepy.go
> $ file sleepy
> sleepy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically 
> linked, not stripped
>
> Then "strip sleepy" gives me a binary which is almost, but not quite, the 
> same size as the one from "go run".  So that gives you another way to try 
> to reproduce the problem - although if the difference is just between 
> stripped and unstripped, then it's most likely some sort of edge timing 
> case.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ab903dd7-512d-49b4-ae6e-197b0c8a18b5n%40googlegroups.com.


[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Brian Candler
On Monday, 11 April 2022 at 09:26:28 UTC+1 scorr...@gmail.com wrote:

> and the output keeps growing like that with every new curl request until 
> eventually it starts constantly printing output like this:
>
>>
>> [pid 143818] 10:02:22.697120 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.707609 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.718125 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.728753 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.739195 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.749618 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.760160 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.770669 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.781137 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.791581 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.802060 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.812540 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.822981 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>> [pid 143818] 10:02:22.833468 nanosleep({tv_sec=0, tv_nsec=1000}, 
>> NULL) = 0
>>
>>
That is normal, I believe, for a process with multiple runnable goroutines 
- one alarm/wakeup call every 10ms.

What is odd is the 100% CPU utilisation.  Can you attach an strace when 
that happens?

As for the binary produced by "go run" - use "ps" to see where it is.  For 
example:

==> sleepy.go <==
package main

import (
"sync"
"time"
)

func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
time.Sleep(30 * time.Second)
wg.Done()
}()
wg.Wait()
}
==> end <==

$ go run sleepy.go

... in another window ...
$ ps auxwww | grep sleepy
ubuntu 17743  0.0  0.1 1237424 12428 pts/1   Sl+  11:23   0:00 go run 
sleepy.go
ubuntu 17782  0.0  0.0 702468  1052 pts/1Sl+  11:23   0:00 
/tmp/go-build2834561198/b001/exe/sleepy

You can 'cp' it somewhere to keep it safe.

If I compare this with the output of "go build sleepy.go", I see that the 
"go build" version is larger and unstripped:

$ cp /tmp/go-build2834561198/b001/exe/sleepy sleepy-run
$ file sleepy-run
sleepy-run: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically 
linked, stripped
$ go build sleepy.go
$ file sleepy
sleepy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically 
linked, not stripped

Then "strip sleepy" gives me a binary which is almost, but not quite, the 
same size as the one from "go run".  So that gives you another way to try 
to reproduce the problem - although if the difference is just between 
stripped and unstripped, then it's most likely some sort of edge timing 
case.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/709d99c5-82a5-4b71-b1a0-11acf5a21f6cn%40googlegroups.com.


Re: [go-nuts] float exactness

2022-04-11 Thread Sam Hughes
Noting that what @Brian%20Candler just said is bang on, I'll add that if 
you use `math.Nextafter(y, math.Round(y))` or  `y - 
math.Nextafter(math.Mod(y, 0.01), math.Round(y))`, you can clean up a 
poorly represented number. The following is Brian's example, but with those 
two algorithms presented: https://go.dev/play/p/C8qXVOO1jPY The first one 
will be faster always.

An alternative is to use an integer with a packed region as integral and an 
8-12 bit decimal component. Call it 9 bits. That gives you a denominator 
for the remainder of 1024. To extract the packed value, you can use 
bitshift and bitwise and ops as follows: `fmt.Printf("v is %v.%vx", v >> 9, 
v & 1023)`, depending. If you're intrigued, try playing with different 
numbers 
here: https://www.rapidtables.com/convert/number/decimal-to-binary.html 

You should check  "0.2" out 
at https://baseconvert.com/ieee-754-floating-point to understand what's 
happening. @bmhad threw a link at you that explains how floating point 
numbers work, but this lets you observe how specific numbers are stored, 
and why a specific number you want to store, such as 0.2, is a really, 
really hard.

After checking that out, you'll understand why the algorithms I suggested 
help, and also why they might not always arrive at the precision you want. 
If this concerns you, do remember that any other 

On Monday, April 11, 2022 at 2:04:16 AM UTC-5 Brian Candler wrote:

> According to the go spec 
> :
> "Constant expressions are always evaluated exactly; intermediate values 
> and the constants themselves may require precision significantly larger 
> than supported by any predeclared type in the language"
>
> Hence there's a difference between:
> * doing an exact addition of 0.1 + 0.2 , then converting the exact value 
> 0.3 to a float64; versus
> * converting 0.1 to float64, converting 0.2 to a float64, and then adding 
> them using float64 precision.
>
> https://go.dev/play/p/x7vf_064RUf
>
> On Sunday, 10 April 2022 at 22:16:21 UTC+1 wagner riffel wrote:
>
>> On Sat Apr 9, 2022 at 3:56 PM CEST, 'Jack Li' via golang-nuts wrote: 
>> > Why literal operation is exact, variable is not? 
>> > 
>> > fmt.Println(0.1 + 0.2) // 0.3 exactly 
>> > fmt.Println(x + y) // 0.30004 
>> > 
>>
>> Both aren't exact because floats can't represent 0.3 exactly, they 
>> differ because literals and constants expressions have arbitrary 
>> precision (http://golang.org/ref/spec/#Constants), so "0.1" and "0.2" 
>> in "0.1 + 0.2" are exact, then when the exact "0.3" result is 
>> converted to a float64 it becomes the closest possible, You can check 
>> this if you ask to print with more precision 
>>
>> x, y := 0.1, 0.2 
>> fmt.Printf("%.17f...\n", 0.1+0.2) // 0.2... 
>> fmt.Printf("%.17f...\n", x+y) // 0.30004... 
>>
>> https://go.dev/play/p/2qSfoCZGaD6 
>>
>> -w 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/83326013-f9ed-419e-9858-3ba3a061428cn%40googlegroups.com.


[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Santiago Corredoira
I discovered this in another very similar pc, a bit older Lenovo Legion 
laptop:

$ grep "model" /proc/cpuinfo | sort | uniq -c
 12 model: 158
 12 model name: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz

$ uname -r
5.4.0-107-generic

$ cat /etc/*ease
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=19.3

The 100% CPU spikes would sart at any moment and would usually stop after a 
I made a new http request to the server.


El lunes, 11 de abril de 2022 a las 10:15:23 UTC+2, Santiago Corredoira 
escribió:

> Hi Brian, thanks for your help.
>
> Al my go downloads are from go.dev
> In this tests I am using
>
> $ go version
> go version go1.18 linux/amd64
>
> I run the tests in a laptop with linux as the main OS, no emulation.
>
> $ grep "model" /proc/cpuinfo | sort | uniq -c
>  12 model: 165
>  12 model name: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
>
> $ uname -r
> 5.4.0-107-generic
>
> $ cat /etc/os-release
> NAME="Linux Mint"
> VERSION="20.3 (Una)"
>
> I just spent 5 hours obsesively trying to reproduce it and I know it 
> sounds very strange. The 100% CPU spikes is how I started noticing this, 
> because the laptop fan would start spinning at full speed. Since then, I am 
> using go1.16 from go.dev and "go install golang.org/dl/go1.16@latest && 
> go1.16 download" and I haven't experienced it again.
>
> I checked the issue links and it seems similar to what I am seeing, but 
> only from version 1.17 and on. Also they say you can dissable it with 
> GODEBUG=asyncpreemptoff=1 but I see the problem in the build version. Maybe 
> the difference with go run is that it probably adds debug flags? I expected 
> it to just compile the program in a temp location and run it, but this is a 
> consistent difference I just tested:
>
> $ go run test.go
>
> And in another console:
>
> $ ps aux | grep test.go
> bill  143464  2.5  0.1 1897584 16480 pts/3   Sl+  09:54   0:00 go run 
> test.go
> bill  143604  0.0  0.0  11568  2764 pts/4S+   09:54   0:00 grep 
> --color=auto test.go
> $ sudo strace -f -tt -p 143464
> strace: Process 143464 attached with 17 threads
> [pid 143544] 09:54:42.564230 futex(0xc000224148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143485] 09:54:42.564321 futex(0xc00056a148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143478] 09:54:42.564340 epoll_pwait(4,  
> [pid 143477] 09:54:42.564366 futex(0xc000580548, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143476] 09:54:42.564386 futex(0xc000680148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143475] 09:54:42.564407 futex(0xc000580148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143474] 09:54:42.564430 futex(0xc000500148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143473] 09:54:42.564451 futex(0xdf3e80, FUTEX_WAIT_PRIVATE, 0, NULL 
> 
> [pid 143472] 09:54:42.564471 futex(0xc000400148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143471] 09:54:42.564493 futex(0xc000380148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143470] 09:54:42.564515 futex(0xc000300148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143469] 09:54:42.564535 futex(0xdf3d38, FUTEX_WAIT_PRIVATE, 0, NULL 
> 
> [pid 143468] 09:54:42.564556 futex(0xc90148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143467] 09:54:42.564576 futex(0xc23148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143466] 09:54:42.564596 futex(0xc22d48, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143465] 09:54:42.564616 restart_syscall(<... resuming interrupted 
> read ...> 
> [pid 143464] 09:54:42.564637 waitid(P_PID, 143586,  
> [pid 143465] 09:55:14.806222 <... restart_syscall resumed>) = -1 ETIMEDOUT 
> (Connection timed out)
> [pid 143465] 09:55:14.806608 nanosleep({tv_sec=0, tv_nsec=2}, NULL) = 0
> [pid 143465] 09:55:14.807053 futex(0xdc55d8, FUTEX_WAIT_PRIVATE, 0, 
> {tv_sec=60, tv_nsec=0}
>
> In another console I would request multiple times:
>
> $ curl http://localhost:8080
> or
> $ wrk -d2 http://localhost:8080
>
> but strace won't show anything else. It just stays like that and CPU's 
> show 0% activity when is not getting requests.
>
> On the other hand, if I compile it:
>
> $ go build test.go
> $ ./test 
>
> Check strace in another console, it starts like this:
>
> $ ps aux | grep ./test
> bill  143817  0.0  0.0 1077296 4448 pts/3Sl+  09:57   0:00 ./test
> bill  143829  0.0  0.0  11568   712 pts/4S+   09:58   0:00 grep 
> --color=auto ./test
> $ sudo strace -f -tt -p 143817
> strace: Process 143817 attached with 6 threads
> [pid 143818] 09:58:23.811515 restart_syscall(<... resuming interrupted 
> read ...> 
> [pid 143822] 09:58:23.811538 futex(0x85f438, FUTEX_WAIT_PRIVATE, 0, NULL 
> 
> [pid 143821] 09:58:23.811561 futex(0xc80148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143820] 09:58:23.811580 futex(0xc15148, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143819] 09:58:23.811585 futex(0xc14d48, FUTEX_WAIT_PRIVATE, 0, 
> NULL 
> [pid 143817] 09:58:23.811613 epoll_pwait(5, 
>
> But below is what I get with a single curl request:
>
> $ sudo strace -f -tt -p 143817
> strace: Process 143817 attached with 6

[go-nuts] Re: Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-11 Thread Santiago Corredoira
Hi Brian, thanks for your help.

Al my go downloads are from go.dev
In this tests I am using

$ go version
go version go1.18 linux/amd64

I run the tests in a laptop with linux as the main OS, no emulation.

$ grep "model" /proc/cpuinfo | sort | uniq -c
 12 model: 165
 12 model name: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz

$ uname -r
5.4.0-107-generic

$ cat /etc/os-release
NAME="Linux Mint"
VERSION="20.3 (Una)"

I just spent 5 hours obsesively trying to reproduce it and I know it sounds 
very strange. The 100% CPU spikes is how I started noticing this, because 
the laptop fan would start spinning at full speed. Since then, I am using 
go1.16 from go.dev and "go install golang.org/dl/go1.16@latest && go1.16 
download" and I haven't experienced it again.

I checked the issue links and it seems similar to what I am seeing, but 
only from version 1.17 and on. Also they say you can dissable it with 
GODEBUG=asyncpreemptoff=1 but I see the problem in the build version. Maybe 
the difference with go run is that it probably adds debug flags? I expected 
it to just compile the program in a temp location and run it, but this is a 
consistent difference I just tested:

$ go run test.go

And in another console:

$ ps aux | grep test.go
bill  143464  2.5  0.1 1897584 16480 pts/3   Sl+  09:54   0:00 go run 
test.go
bill  143604  0.0  0.0  11568  2764 pts/4S+   09:54   0:00 grep 
--color=auto test.go
$ sudo strace -f -tt -p 143464
strace: Process 143464 attached with 17 threads
[pid 143544] 09:54:42.564230 futex(0xc000224148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143485] 09:54:42.564321 futex(0xc00056a148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143478] 09:54:42.564340 epoll_pwait(4,  
[pid 143477] 09:54:42.564366 futex(0xc000580548, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143476] 09:54:42.564386 futex(0xc000680148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143475] 09:54:42.564407 futex(0xc000580148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143474] 09:54:42.564430 futex(0xc000500148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143473] 09:54:42.564451 futex(0xdf3e80, FUTEX_WAIT_PRIVATE, 0, NULL 

[pid 143472] 09:54:42.564471 futex(0xc000400148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143471] 09:54:42.564493 futex(0xc000380148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143470] 09:54:42.564515 futex(0xc000300148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143469] 09:54:42.564535 futex(0xdf3d38, FUTEX_WAIT_PRIVATE, 0, NULL 

[pid 143468] 09:54:42.564556 futex(0xc90148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143467] 09:54:42.564576 futex(0xc23148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143466] 09:54:42.564596 futex(0xc22d48, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143465] 09:54:42.564616 restart_syscall(<... resuming interrupted read 
...> 
[pid 143464] 09:54:42.564637 waitid(P_PID, 143586,  
[pid 143465] 09:55:14.806222 <... restart_syscall resumed>) = -1 ETIMEDOUT 
(Connection timed out)
[pid 143465] 09:55:14.806608 nanosleep({tv_sec=0, tv_nsec=2}, NULL) = 0
[pid 143465] 09:55:14.807053 futex(0xdc55d8, FUTEX_WAIT_PRIVATE, 0, 
{tv_sec=60, tv_nsec=0}

In another console I would request multiple times:

$ curl http://localhost:8080
or
$ wrk -d2 http://localhost:8080

but strace won't show anything else. It just stays like that and CPU's show 
0% activity when is not getting requests.

On the other hand, if I compile it:

$ go build test.go
$ ./test 

Check strace in another console, it starts like this:

$ ps aux | grep ./test
bill  143817  0.0  0.0 1077296 4448 pts/3Sl+  09:57   0:00 ./test
bill  143829  0.0  0.0  11568   712 pts/4S+   09:58   0:00 grep 
--color=auto ./test
$ sudo strace -f -tt -p 143817
strace: Process 143817 attached with 6 threads
[pid 143818] 09:58:23.811515 restart_syscall(<... resuming interrupted read 
...> 
[pid 143822] 09:58:23.811538 futex(0x85f438, FUTEX_WAIT_PRIVATE, 0, NULL 

[pid 143821] 09:58:23.811561 futex(0xc80148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143820] 09:58:23.811580 futex(0xc15148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143819] 09:58:23.811585 futex(0xc14d48, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143817] 09:58:23.811613 epoll_pwait(5, 

But below is what I get with a single curl request:

$ sudo strace -f -tt -p 143817
strace: Process 143817 attached with 6 threads
[pid 143818] 09:58:23.811515 restart_syscall(<... resuming interrupted read 
...> 
[pid 143822] 09:58:23.811538 futex(0x85f438, FUTEX_WAIT_PRIVATE, 0, NULL 

[pid 143821] 09:58:23.811561 futex(0xc80148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143820] 09:58:23.811580 futex(0xc15148, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143819] 09:58:23.811585 futex(0xc14d48, FUTEX_WAIT_PRIVATE, 0, 
NULL 
[pid 143817] 09:58:23.811613 epoll_pwait(5,  
[pid 143818] 09:58:42.447774 <... restart_syscall resumed>) = -1 ETIMEDOUT 
(Connection timed out)
[pid 143818] 09:58:42.447898 nanosleep({tv_sec=0, tv_nsec=2}, NULL) = 0
[pid 143818] 09:58:42.448141 futex(0x830ed8, FUTEX_WAIT_PRIVATE, 0, 
{tv_sec=60, tv_nsec=0} 
[pid 143817] 09:59:

[go-nuts] Re: YAML Unmarshal changes keys

2022-04-11 Thread vika...@gmail.com
Thanks a ton for the explanation and for helping to fix the issue. I will 
keep the yaml library in mind.

On Monday, 11 April 2022 at 15:44:58 UTC+10 sam.a@gmail.com wrote:

> I skipped over to that package, and the doc says it converts from yaml to 
> json, and the marshals/unmarshals. I tried changing your snippet to use 
> struct tags with the key name as "json" instead of "yaml", and it 
> immediately behaved as expected: https://goplay.tools/snippet/PSZtr1YErD8
>
> While you're fine to use it like you are, the package you're using is a 
> wrapper around another tool, pkg.go.dev/gopkg.in/yaml.v2, using that tool 
> to convert to/from json, and then using encode/json to marshal/unmarshal. 
> The benefit would be using common marshal/unmarshal handlers and one set of 
> struct tags. Meanwhile, you're not interacting with both yaml and json, so 
> I suggest actually changing the tool you're using to support yaml directly.
>
> 1. Simple fix: replace `yaml:""` with `json:""`
> 2. Better fix that might break some code: use gopkg.in/yaml.v2 instead of 
> github.com/ghodss/yaml, to avoid unexpected behavior, such as what you 
> observed.
>
> On Sunday, April 10, 2022 at 11:53:57 PM UTC-5 vika...@gmail.com wrote:
>
>> I am new to GoLang and looking to join two keys (rules) from two 
>> different Yamls.
>>
>> I have been able to join the keys but I found that Unmarshal changes the 
>> keys (example apiVersion to APIVersion, and kind to Kind).
>>
>> Overall, my goal is to have a valid Kubernetes YAML manifest. This is 
>> what I have attempted so far https://goplay.tools/snippet/zWYDjnTeA0Q 
>>
>> ## 
>> package main
>>
>> import (
>> "fmt"
>>
>> "github.com/InVisionApp/conjungo"
>> "github.com/ghodss/yaml"
>> )
>>
>> type ClusterRole struct {
>> APIVersion string `yaml:"apiVersion"`
>> Kind string `yaml:"kind"`
>> Metadata struct {
>> Name string `yaml:"name"`
>> } `yaml:"metadata"`
>> Rules []struct {
>> APIGroups []string `yaml:"apiGroups"`
>> Resources []string `yaml:"resources"`
>> Verbs []string `yaml:"verbs"`
>> } `yaml:"rules"`
>> }
>>
>> func main() {
>>
>> yaml1 := `
>> ---
>> apiVersion: rbac.authorization.k8s.io/v1
>> kind: ClusterRole
>> metadata:
>> name: role1
>> rules:
>> - apiGroups:
>> - ""
>> resources:
>> - services
>> verbs:
>> - create
>> - delete
>> - apiGroups:
>> - apiregistration.k8s.io
>> resources:
>> - apiservices
>> verbs:
>> - create
>> - delete
>> `
>>
>> yaml2 := `
>> ---
>> apiVersion: rbac.authorization.k8s.io/v1
>> kind: ClusterRole
>> metadata:
>> name: role2
>> rules:
>> - apiGroups:
>> - ""
>> resources:
>> - secrets
>> - events.k8s.io
>> verbs:
>> - list
>> - watch
>> - apiGroups:
>> - metrics.k8s.io
>> resources:
>> - nodes
>> - bindings
>> verbs:
>> - get
>> `
>>
>> var role1 ClusterRole
>> yaml.Unmarshal([]byte(yaml1), &role1)
>> fmt.Printf("\n## ROLE1\n %v", role1)
>>
>> var role2 ClusterRole
>> yaml.Unmarshal([]byte(yaml2), &role2)
>> fmt.Printf("\n\n## ROLE2\n %v", role2)
>>
>> conjungo.Merge(&role1, role2, nil)
>>
>> // Struct to Marshal
>> y, err := yaml.Marshal(role1)
>> if err != nil {
>> fmt.Printf("\nerr: %v\n", err)
>> return
>> }
>> fmt.Printf("\n\n## MERGED ROLE\n %v", string(y))
>> }
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/dc371393-dff6-491d-96f7-7ae943ce384an%40googlegroups.com.


Re: [go-nuts] float exactness

2022-04-11 Thread Brian Candler
According to the go spec 
:
"Constant expressions are always evaluated exactly; intermediate values and 
the constants themselves may require precision significantly larger than 
supported by any predeclared type in the language"

Hence there's a difference between:
* doing an exact addition of 0.1 + 0.2 , then converting the exact value 
0.3 to a float64; versus
* converting 0.1 to float64, converting 0.2 to a float64, and then adding 
them using float64 precision.

https://go.dev/play/p/x7vf_064RUf

On Sunday, 10 April 2022 at 22:16:21 UTC+1 wagner riffel wrote:

> On Sat Apr 9, 2022 at 3:56 PM CEST, 'Jack Li' via golang-nuts wrote:
> > Why literal operation is exact, variable is not?
> >
> > fmt.Println(0.1 + 0.2) // 0.3 exactly
> > fmt.Println(x + y) // 0.30004
> >
>
> Both aren't exact because floats can't represent 0.3 exactly, they
> differ because literals and constants expressions have arbitrary
> precision (http://golang.org/ref/spec/#Constants), so "0.1" and "0.2"
> in "0.1 + 0.2" are exact, then when the exact "0.3" result is
> converted to a float64 it becomes the closest possible, You can check
> this if you ask to print with more precision
>
> x, y := 0.1, 0.2
> fmt.Printf("%.17f...\n", 0.1+0.2) // 0.2...
> fmt.Printf("%.17f...\n", x+y) // 0.30004...
>
> https://go.dev/play/p/2qSfoCZGaD6
>
> -w
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a487a8bb-caf7-4b74-b81c-93d3d689a5ecn%40googlegroups.com.