Initial
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
__pycache__
|
||||
/dist
|
||||
/src/funnel/env
|
||||
95
README.md
Normal file
95
README.md
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
# Clocker
|
||||
|
||||
## Sequence diagram
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
participant FE as "Frontend" << React >>
|
||||
participant Funnel as "Funnel" << Python >>
|
||||
participant Hours as "ServeHours" << Go >>
|
||||
participant Minutes as "ServeMinutes" << Go >>
|
||||
participant Seconds as "ServeSeconds" << Go >>
|
||||
participant Milliseconds as "ServeMilliseconds" << Go >>
|
||||
participant CurrentTime as "ServeCurrentTime" << Rust >>
|
||||
|
||||
activate FE #hotpink
|
||||
FE -> FE: Load page
|
||||
FE -> Funnel: WS Connect
|
||||
|
||||
loop #ivory
|
||||
activate Funnel #gold
|
||||
Funnel -> Hours: GetHours()
|
||||
activate Hours #skyblue
|
||||
Hours -> CurrentTime: GetCurrentTime()
|
||||
activate CurrentTime #sandybrown
|
||||
return HH:MM:SS.ms
|
||||
return HH
|
||||
|
||||
Funnel -> Minutes: GetMinutes()
|
||||
activate Minutes #skyblue
|
||||
Minutes -> CurrentTime: GetCurrentTime()
|
||||
activate CurrentTime #sandybrown
|
||||
return HH:MM:SS.ms
|
||||
return MM
|
||||
|
||||
Funnel -> Seconds: GetSeconds()
|
||||
activate Seconds #skyblue
|
||||
Seconds -> CurrentTime: GetCurrentTime()
|
||||
activate CurrentTime #sandybrown
|
||||
return HH:MM:SS.ms
|
||||
return SS
|
||||
|
||||
Funnel -> Milliseconds: GetMilliseconds()
|
||||
activate Milliseconds #skyblue
|
||||
Milliseconds -> CurrentTime: GetCurrentTime()
|
||||
activate CurrentTime #sandybrown
|
||||
return HH:MM:SS.ms
|
||||
return ms
|
||||
|
||||
Funnel -> FE: WS: Send formatted time
|
||||
deactivate Funnel
|
||||
end
|
||||
deactivate FE
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
## Services
|
||||
|
||||
| Service | Language | Port |
|
||||
| -- | -- | -- |
|
||||
| Funnel | Python | - |
|
||||
| ServeCurrentTime | Rust | 50000 |
|
||||
| ServeHours | Go | 50001 |
|
||||
| ServeMinutes | Go | 50002 |
|
||||
| ServeSeconds | Go | 50003 |
|
||||
| ServeMilliseconds | Go | 50004 |
|
||||
|
||||
### Funnel
|
||||
|
||||
Requirements:
|
||||
- python 3.8+
|
||||
- grpcio
|
||||
- grpcio-tools
|
||||
|
||||
Install virtualenv and libs
|
||||
```sh
|
||||
cd src/funnel
|
||||
virtualenv env
|
||||
source env/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Compile proto stubs:
|
||||
```sh
|
||||
cd src/funnel
|
||||
make proto
|
||||
```
|
||||
|
||||
Run service:
|
||||
```sh
|
||||
cd src/funnel
|
||||
make run
|
||||
```
|
||||
|
||||
18
src/funnel/Makefile
Normal file
18
src/funnel/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
PROTO_DIR=../protos
|
||||
STUBS_DIR=./stubs
|
||||
PROTO_FILENAME=serve_hours.proto
|
||||
|
||||
run:
|
||||
@source env/bin/activate && \
|
||||
python main.py
|
||||
|
||||
proto:
|
||||
@source env/bin/activate && \
|
||||
python \
|
||||
-m grpc_tools.protoc \
|
||||
-I$(PROTO_DIR) \
|
||||
--python_out=$(STUBS_DIR) \
|
||||
--pyi_out=$(STUBS_DIR) \
|
||||
--grpc_python_out=$(STUBS_DIR) \
|
||||
$(PROTO_DIR)/$(PROTO_FILENAME)
|
||||
@sed -i -E 's/^(import\s[a-zA-Z0-9_]+_pb2)/from . \1/g' $(STUBS_DIR)/*_grpc.py
|
||||
33
src/funnel/main.py
Normal file
33
src/funnel/main.py
Normal file
@ -0,0 +1,33 @@
|
||||
import logging
|
||||
import grpc
|
||||
from stubs import serve_hours_pb2
|
||||
from stubs import serve_hours_pb2_grpc
|
||||
|
||||
SERVE_HOURS_HOST = "localhost"
|
||||
SERVE_HOURS_PORT = 50001
|
||||
SERVE_MINUTES_HOST = "localhost"
|
||||
SERVE_MINUTES_PORT = 50002
|
||||
SERVE_SECONDS_HOST = "localhost"
|
||||
SERVE_SECONDS_PORT = 50003
|
||||
SERVE_MILLISECONDS_HOST = "localhost"
|
||||
SERVE_MILLISECONDS_PORT = 50004
|
||||
|
||||
TIMEZONE = "Europe/Zagreb"
|
||||
|
||||
|
||||
def get_hours() -> int:
|
||||
with grpc.insecure_channel(f"{SERVE_HOURS_HOST}:{SERVE_HOURS_PORT}") as channel:
|
||||
stub = serve_hours_pb2_grpc.ServeHoursStub(channel)
|
||||
response = stub.GetHours(serve_hours_pb2.GetHoursRequest(timezone=TIMEZONE))
|
||||
print("GetHours() response: " + response.message)
|
||||
return response.hours
|
||||
|
||||
|
||||
def run():
|
||||
hours = get_hours()
|
||||
print(">>>>>>>>>>>>> Hours:", hours)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig()
|
||||
run()
|
||||
2
src/funnel/requirements.txt
Normal file
2
src/funnel/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
grpcio
|
||||
grpcio-tools
|
||||
0
src/funnel/stubs/__init__.py
Normal file
0
src/funnel/stubs/__init__.py
Normal file
29
src/funnel/stubs/serve_hours_pb2.py
Normal file
29
src/funnel/stubs/serve_hours_pb2.py
Normal file
@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: serve_hours.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11serve_hours.proto\"#\n\x0fGetHoursRequest\x12\x10\n\x08timezone\x18\x01 \x01(\t\"!\n\x10GetHoursResponse\x12\r\n\x05hours\x18\x01 \x01(\r2=\n\nServeHours\x12/\n\x08GetHours\x12\x10.GetHoursRequest\x1a\x11.GetHoursResponseb\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'serve_hours_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
_GETHOURSREQUEST._serialized_start=21
|
||||
_GETHOURSREQUEST._serialized_end=56
|
||||
_GETHOURSRESPONSE._serialized_start=58
|
||||
_GETHOURSRESPONSE._serialized_end=91
|
||||
_SERVEHOURS._serialized_start=93
|
||||
_SERVEHOURS._serialized_end=154
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
17
src/funnel/stubs/serve_hours_pb2.pyi
Normal file
17
src/funnel/stubs/serve_hours_pb2.pyi
Normal file
@ -0,0 +1,17 @@
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class GetHoursRequest(_message.Message):
|
||||
__slots__ = ["timezone"]
|
||||
TIMEZONE_FIELD_NUMBER: _ClassVar[int]
|
||||
timezone: str
|
||||
def __init__(self, timezone: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class GetHoursResponse(_message.Message):
|
||||
__slots__ = ["hours"]
|
||||
HOURS_FIELD_NUMBER: _ClassVar[int]
|
||||
hours: int
|
||||
def __init__(self, hours: _Optional[int] = ...) -> None: ...
|
||||
66
src/funnel/stubs/serve_hours_pb2_grpc.py
Normal file
66
src/funnel/stubs/serve_hours_pb2_grpc.py
Normal file
@ -0,0 +1,66 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
"""Client and server classes corresponding to protobuf-defined services."""
|
||||
import grpc
|
||||
|
||||
from . import serve_hours_pb2 as serve__hours__pb2
|
||||
|
||||
|
||||
class ServeHoursStub(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
def __init__(self, channel):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
channel: A grpc.Channel.
|
||||
"""
|
||||
self.GetHours = channel.unary_unary(
|
||||
'/ServeHours/GetHours',
|
||||
request_serializer=serve__hours__pb2.GetHoursRequest.SerializeToString,
|
||||
response_deserializer=serve__hours__pb2.GetHoursResponse.FromString,
|
||||
)
|
||||
|
||||
|
||||
class ServeHoursServicer(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
def GetHours(self, request, context):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
|
||||
def add_ServeHoursServicer_to_server(servicer, server):
|
||||
rpc_method_handlers = {
|
||||
'GetHours': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.GetHours,
|
||||
request_deserializer=serve__hours__pb2.GetHoursRequest.FromString,
|
||||
response_serializer=serve__hours__pb2.GetHoursResponse.SerializeToString,
|
||||
),
|
||||
}
|
||||
generic_handler = grpc.method_handlers_generic_handler(
|
||||
'ServeHours', rpc_method_handlers)
|
||||
server.add_generic_rpc_handlers((generic_handler,))
|
||||
|
||||
|
||||
# This class is part of an EXPERIMENTAL API.
|
||||
class ServeHours(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
@staticmethod
|
||||
def GetHours(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/ServeHours/GetHours',
|
||||
serve__hours__pb2.GetHoursRequest.SerializeToString,
|
||||
serve__hours__pb2.GetHoursResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
15
src/protos/serve_current_time.proto
Normal file
15
src/protos/serve_current_time.proto
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service ServeCurrentTime {
|
||||
rpc GetCurrentTime(GetCurrentTimeRequest) returns (GetCurrentTimeResponse);
|
||||
}
|
||||
|
||||
message GetCurrentTimeRequest { string timezone = 1; }
|
||||
|
||||
message GetCurrentTimeResponse {
|
||||
uint32 hours = 1;
|
||||
uint32 minutes = 2;
|
||||
uint32 seconds = 3;
|
||||
uint32 milliseconds = 4;
|
||||
string formatted_time = 5;
|
||||
}
|
||||
7
src/protos/serve_hours.proto
Normal file
7
src/protos/serve_hours.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service ServeHours { rpc GetHours(GetHoursRequest) returns (GetHoursResponse); }
|
||||
|
||||
message GetHoursRequest { string timezone = 1; }
|
||||
|
||||
message GetHoursResponse { uint32 hours = 1; }
|
||||
9
src/protos/serve_milliseconds.proto
Normal file
9
src/protos/serve_milliseconds.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service ServeMilliseconds {
|
||||
rpc GetMilliseconds(GetMillisecondsRequest) returns (GetMillisecondsResponse);
|
||||
}
|
||||
|
||||
message GetMillisecondsRequest { string timezone = 1; }
|
||||
|
||||
message GetMillisecondsResponse { uint32 milliseconds = 1; }
|
||||
9
src/protos/serve_minutes.proto
Normal file
9
src/protos/serve_minutes.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service ServeMinutes {
|
||||
rpc GetMinutes(GetMinutesRequest) returns (GetMinutesResponse);
|
||||
}
|
||||
|
||||
message GetMinutesRequest { string timezone = 1; }
|
||||
|
||||
message GetMinutesResponse { uint32 minutes = 1; }
|
||||
9
src/protos/serve_seconds.proto
Normal file
9
src/protos/serve_seconds.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service ServeSeconds {
|
||||
rpc GetSeconds(GetSecondsRequest) returns (GetSecondsResponse);
|
||||
}
|
||||
|
||||
message GetSecondsRequest { string timezone = 1; }
|
||||
|
||||
message GetSecondsResponse { uint32 seconds = 1; }
|
||||
Reference in New Issue
Block a user