LINUX.ORG.RU

Как правильно организовать код на Go

 


0

3

Например, если создаем web-app в которой данные передаются в json формате, то:

Сначала нужно создать структуру

type JsonMessage struct {
	Type string
	Data json.RawMessage
}

Потом нужно создать под каждый запрос свою структуру

type ChatMessage struct {
	Username    string `json:"Username"`
	Message     string `json:"ConnectedTo"`
	ChatId      int    `json:"ChatId"`
}

Потом нужно создать обработчик

var msg JsonMessage
err = json.Unmarshal(message, &msg)
if err != nil {
	log.Println("Message decode failed")
	return
} 
switch msg.Type {
case "ChatMessage":
	{
		var cmsg ChatMessage
		err = json.Unmarshal(msg.Data, &cmsg)
		if err != nil {
			log.Println("Chat message decode failed")
			return
		}
		// ToDo ...
	}
	// ToDo ...
}

И в этом обработчике придется описать все возможные типы сообщений, в итоге код разрастается и становится трудным для понимания.

Посоветуйте что прочитать чтобы понять как правильно проектировать программу на Go, разбивать ее по файлам и модулям.



Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от derlafff

Диска? Сирисли? Два десятка мегабайт разницы тебя беспокоят?

А если у тебя на сервере 100 процессов Python или Go? Python вполне может и рвать Го.

А уж как я наелся этих бинарей на Clipper.... Спасибо

dem ★★
()
Ответ на: комментарий от dem

Еще раз. Го переоценен. 99% фирм хотят лучшую производительность БЕСПЛАТНО. Но они просто теряют время.

Еще одна череда потока сознания, подтвержденного только примером личного неосиляторства.

derlafff ★★★★★
()
Ответ на: комментарий от dem

А если у тебя на сервере 100 процессов Python или Go? Python вполне может и рвать Го.

Нет ни одной причины запускать 100 процессов go по старой «питоньей памяти». А даже на десятке нет никакой значительной разницы.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от derlafff

Еще раз: они будут исполнятся в порядке, удобном планировщику.

Тоесть у тебя есть 2 потока. 1 пишет и читает в БД. Второй пишет и читает в сеть. Общаются через shared memory и у тебя 80 ядер. Предположим 1-й поток считал данные из базы и пульнул в shared memory (ой она есть в Го или только пайпы?) null copy и все такое. А второй хочет считать и отправить по сети. Что они делают?

dem ★★
()
Ответ на: комментарий от derlafff

А даже на десятке нет никакой значительной разницы.

Ффф. Ну вот яж спросил оно само или автоматически. Ну что ты совсем не понимаешь?

dem ★★
()
Ответ на: комментарий от dem

Давай расскажи как ты управляешь горутины будут работать паралельно или конкурентно? Вот честно

Ты тупой что ли? Я же написал: никак. Горутины не про параллельность. Конкурентность ≠ параллелизм. Что тут не понятно?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Ты не так сказал. Ты сказал

Могут, но не обязаны. Ещё раз, конкурентность — про организацию кода / архитектуру приложения, как ООП, ФП, ЛП, и прочее *П.

Давай сам уже контролируй что пишешь

dem ★★
()
Ответ на: комментарий от dem

Тоесть у тебя есть 2 потока. 1 пишет и читает в БД. Второй пишет и читает в сеть. Общаются через shared memory и у тебя 80 ядер. Предположим 1-й поток считал данные из базы и пульнул в shared memory (ой она есть в Го или только пайпы?) null copy и все такое. А второй хочет считать и отправить по сети. Что они делают?

Они используют канал, если программист не обезьянка, мечтающая везде запихнуть низкоуровневые неудобные примитивы.

null copy

И отправляют по каналу указатели.

Если кому-то таки нужно использовать общую память, она спокойно используется под защитой того же мьютекса.

derlafff ★★★★★
()
Ответ на: комментарий от dem

Ффф. Ну вот яж спросил оно само или автоматически.

Само или автоматически что? Совсем крыша потекла, да?

derlafff ★★★★★
()
Ответ на: комментарий от dem

Посмотри любой просмотрщик процессов (ps, top, taskmgr, …), посчитай какое там количество процессов и расскажи, как они матчатся с ядрами CPU.

korvin_ ★★★★★
()
Ответ на: комментарий от derlafff

И отправляют по каналу указатели.

В NUMA на разных процах. Удачи вам....

Если кому-то таки нужно использовать общую память, она спокойно используется под защитой того же мьютекса.

Ага теперь мы уже начинаем подозревать...http://local.joelonsoftware.com/wiki/%D0%9D%D0%B5_%D0%B4%D0%B0%D0%B9%D1%82%D0%B5_%D0%90%D1%81%D1%82%D1%80%D0%BE%D0%BD%D0%B0%D0%B2%D1%82%D0%B0%D0%BC_%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B2%D0%B0%D1%81_%D0%B7%D0%B0%D0%BF%D1%83%D0%B3%D0%B0%D1%82%D1%8C

dem ★★
()
Ответ на: комментарий от korvin_

Как «»не так»? «Не так» по сравнению с чем?

Ты сказал МОГУТ, но не ДОЛЖНЫ. Вот я и спрашиваю как это решается...

dem ★★
()
Ответ на: комментарий от dem

Общаются через shared memory и у тебя 80 ядер. Предположим 1-й поток считал данные из базы и пульнул в shared memory (ой она есть в Го или только пайпы?) null copy и все такое. А второй хочет считать и отправить по сети. Что они делают?

Они делают баги и прочую херню.

https://www.youtube.com/watch?v=2yXtZ8x7TXw

korvin_ ★★★★★
()
Ответ на: комментарий от dem

Ты сказал МОГУТ, но не ДОЛЖНЫ. Вот я и спрашиваю как это решается...

В глазки долбишься?

горутины управляются рантаймом языка, некоторые из них раскидываются по разным тредам ОС.

Как правильно организовать код на Go (комментарий)

korvin_ ★★★★★
()
Ответ на: комментарий от derlafff

Опять он некорректен. Возьми 300 процессов и получишь иное. А если еще и планировку руками сделать то внезапно все изменится. Ну даже это не главное. А потом пусть эти процессы читают и пишут в PostgreSQL и в сеть. И ВНЕЗАПНО....

dem ★★
()
Ответ на: комментарий от dem

Ясно. Тоесть преимущество в планировщике в ГО уже ушло в никуда.

Ясно. Вывод из пальца на уровне шаманов 10-го века до н.э.

korvin_ ★★★★★
()
Ответ на: комментарий от dem

И потом пусть эти процессы читают и пишут в PostgreSQL и в сеть. И ВНЕЗАПНО....

И ВНЕЗАПНО питону нужно еще 100 процессов, и они все равно всирают одному процессу на go

derlafff ★★★★★
()
Ответ на: комментарий от korvin_

В глазки долбишься?

Я хочу чтоб ты сам читал то, что сам пишешь. Как ты можешь вмешаться в рантайм?

dem ★★
()
Ответ на: комментарий от derlafff

И ВНЕЗАПНО питону нужно еще 100 процессов

Как показывает практика 99% все они (корутины) ждут IO... Только На гошечке ты потратишь в 10 раз больше времени на написание кода лепя свои if error на каждую строку. А потом потеряешь свой код и поймешь что - все...

dem ★★
()
Ответ на: комментарий от dem

Я хочу чтоб ты сам читал то, что сам пишешь. Как ты можешь вмешаться в рантайм?

кто говорил о вмешательстве в рантайм? Ты предложения на ходу выдумываешь? Ты, часом, не бот?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Нет. Я еще раз для тех кто в танке. В БОЛЬШИНСТВЕ случаев код на Python можно сделать сравнимым с Go. Я не спорю, что он быстрее ибо сам тупее, но у программиста время тоже стоит и код на Python будет написан БЫСТРЕЕ. И ты не гугл чтоб поделить эти деньги на 1 млн серверов и получить выгоду. Чаще всего прогер на python будет эффективнее.

Про потерю кода я писал? Какая версия у тебя на сервере XYZ? Почему в ней есть ошибки, а на ZYX нет? Дифф можешь показать?

dem ★★
()
Ответ на: комментарий от korvin_

Ты, часом, не бот?

Макском ИИ испытывает

dem ★★
()
Ответ на: комментарий от tailgunner

Ну это из без комментариев было ясно. Хотя автор знатно продолбался, ведь в go планировщик может прервать выполнение рутины на каждом рекурсивном вызове, а питон нет. Не в курсе, что в питоне делают вместо runtime.Gosched()?

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 2)
Ответ на: комментарий от dem

На асинхронном с await может. На синхронном нет. Либо пруфы обратного, либо GTFO, я уже устал от твоих потоков сознания.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от derlafff

Ну это из без комментариев было ясно.

Из того, что ты любезно процитировал - нет, не ясно.

Не в курсе, что в питоне делают вместо runtime.Gosched()`?

Я даже не знаю, что такое Gosched.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от derlafff

Давай обсуждать Go и Python 2001 года. Как ты а Го 2001 года вызовешь runtime.Gosched()

dem ★★
()
Ответ на: комментарий от derlafff

Хрень полная. Сам подумай почему. И это вообще не то о чем я говорил, там в комментах как раз на это указывают.

Но никто не спорит что go будет быстрее, тем более на cpu-bound tasks. Кстати, там pypy быстрее go лол.

Асинхронный код на питоне может обрабатывать тысячи и десятки тысяч запросов в секунду, запускаешь их по количеству ядер и все. Ну и что-то блокирующее выносить в подпроцессы или в очередь и где-то отдельно обрабатываешь.

pawnhearts ★★★★★
()
Ответ на: комментарий от pawnhearts

Кстати, там pypy быстрее go лол.

Или внезапно берешь numpy и бамс....

dem ★★
()
Ответ на: комментарий от pawnhearts

Но никто не спорит что go будет быстрее, тем более на cpu-bound tasks. Кстати, там pypy быстрее go лол.

Да, но там еще есть и другой косяк в бенчмарке есть, даже не из-за того, что он cpu-based. Сейчас, пробую воспроизвести.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от derlafff

А еще для примера возьми 100 процессов с вызовом numpy (разных) и 100 разных процессов на Го (с разным кодом, пусть тоже считают одинаковове, но экзешники разные) и погляди на потребление памяти. У тебя будет 1 python с 1 numpy и 100 гошек....

dem ★★
()
Ответ на: комментарий от tailgunner

Я даже не знаю, что такое Gosched.

import asyncio

async def foo():

    print('Starting foo')
    await asyncio.sleep(5)
    print('Foo finished')


async def bar():

    print('Starting infinite loop')
    while True:
        pass


async def start():

    tasks = [
            foo(),
            bar(),
    ]

    await asyncio.wait(tasks)

loop = asyncio.get_event_loop()
loop.run_until_complete(start())
loop.close()
% python3 test.py                                                                                                                    :(
Starting foo
Starting infinite loop

Что нужно поставить в бесконечный цикл вместо pass, чтобы управление временно вернулось в ioloop и корутина foo выполнилась до конца? Это и есть gosched и бенчмарк страдает из-за той же проблемы. В go оно выполняется неявно при каждом вызове функции, поэтому проблема именно в том бенчмарке не проявляется.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 2)
Ответ на: комментарий от dem
  1. Добавь любое IO

Не удивлен, что у тебя ничего в продакшоне нормально не работает, лол. Если ты в условную математику предлагаешь добавлять io, чтобы обойти ограничения планировщика.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от derlafff

Что нужно поставить в бесконечный цикл вместо pass, чтобы управление временно вернулось в ioloop

await asyncio.sleep()

Ну где там рекурсия?

dem ★★
()
Ответ на: комментарий от derlafff

Так ты все еще о АСИНХРОНЩИНЕ? Что у тебя тут АСИНХРОННОЕ? Что оно ждет?

dem ★★
()
Ответ на: комментарий от pawnhearts

Медленно?

Точно нет.

Иначе зачем были бы нужны все эти poll

select(2) и poll(2) - практически одно и то же (разные интерфейсы к одной и то же возможности). Питоновский select использует poll, насколько я знаю.

epoll

Некоторые любят edge-triggered, некоторые воображают себя фейсбуком и гуглом.

kqueue

В FreeBSD тоже бывает NIH.

iocp

В других ОС другие игрушки.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от pawnhearts

он не понимает что означает IO в asyncIO

dem ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.