You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2023/05/15 16:06:13 UTC

[plc4x] branch develop updated (c857f837fa -> e9d689fad4)

This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


    from c857f837fa fix(plc4go/spi): fix timing issue when closing cached connection
     new d915511291 refactor(plc4go): use buffered channels when possible
     new e9d689fad4 refactor(plc4go): use constructors when possible for default types

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 plc4go/internal/ads/Browser.go                     | 32 ++++-----
 plc4go/internal/ads/Connection.go                  |  2 +-
 plc4go/internal/ads/Discoverer.go                  | 16 ++---
 plc4go/internal/ads/Driver.go                      |  4 +-
 plc4go/internal/ads/Interactions.go                | 12 ++--
 plc4go/internal/ads/Reader.go                      | 81 +++++++++++-----------
 plc4go/internal/ads/Subscriber.go                  | 47 +++++++------
 plc4go/internal/ads/Writer.go                      | 78 +++++----------------
 plc4go/internal/bacnetip/Connection.go             |  2 +-
 plc4go/internal/bacnetip/Discoverer.go             | 34 +++++----
 plc4go/internal/bacnetip/Driver.go                 | 18 ++---
 plc4go/internal/bacnetip/Reader.go                 | 45 ++++++------
 plc4go/internal/bacnetip/Subscriber.go             | 18 ++---
 plc4go/internal/cbus/Browser.go                    | 18 ++---
 plc4go/internal/cbus/Discoverer.go                 | 15 ++--
 plc4go/internal/cbus/Reader.go                     | 34 ++++-----
 plc4go/internal/cbus/Subscriber.go                 | 15 ++--
 plc4go/internal/cbus/Writer.go                     | 42 +++++------
 plc4go/internal/eip/Connection.go                  |  4 +-
 plc4go/internal/eip/Reader.go                      | 39 ++++++-----
 plc4go/internal/eip/Writer.go                      | 26 ++-----
 plc4go/internal/knxnetip/Browser.go                | 47 ++++++++-----
 plc4go/internal/knxnetip/Connection.go             |  6 +-
 .../knxnetip/ConnectionDriverSpecificOperations.go | 14 ++--
 .../knxnetip/ConnectionInternalOperations.go       | 48 ++++++-------
 plc4go/internal/knxnetip/Discoverer.go             | 15 ++--
 plc4go/internal/knxnetip/Reader.go                 | 12 ++--
 plc4go/internal/knxnetip/Subscriber.go             | 16 ++---
 plc4go/internal/knxnetip/Writer.go                 | 14 +---
 plc4go/internal/modbus/Connection.go               |  2 +-
 plc4go/internal/modbus/Reader.go                   | 69 +++++++++---------
 plc4go/internal/modbus/Writer.go                   | 24 +++----
 plc4go/internal/s7/Connection.go                   | 14 ++--
 plc4go/internal/s7/Reader.go                       | 49 +++++++------
 plc4go/internal/s7/Writer.go                       | 20 ++----
 plc4go/internal/simulated/Connection.go            |  6 +-
 plc4go/internal/simulated/Reader.go                | 12 ++--
 plc4go/internal/simulated/Subscriber.go            | 12 +++-
 plc4go/internal/simulated/Writer.go                |  8 +--
 plc4go/spi/default/DefaultBrowser.go               | 12 ++--
 plc4go/spi/default/DefaultConnection.go            |  4 +-
 plc4go/spi/model/DefaultPlcReadRequest.go          |  4 +-
 plc4go/spi/model/DefaultPlcWriteRequest.go         |  2 +-
 plc4go/spi/utils/Net.go                            |  2 +-
 plc4go/spi/utils/WorkerPool.go                     |  2 +-
 45 files changed, 463 insertions(+), 533 deletions(-)


[plc4x] 01/02: refactor(plc4go): use buffered channels when possible

Posted by sr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit d9155112910be36914c2190b4e2fe3d310708a8f
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon May 15 18:04:59 2023 +0200

    refactor(plc4go): use buffered channels when possible
---
 plc4go/internal/ads/Browser.go                     |  2 +-
 plc4go/internal/ads/Connection.go                  |  2 +-
 plc4go/internal/ads/Driver.go                      |  4 +-
 plc4go/internal/ads/Interactions.go                | 12 +++---
 plc4go/internal/ads/Reader.go                      |  2 +-
 plc4go/internal/ads/Subscriber.go                  |  6 +--
 plc4go/internal/ads/Writer.go                      |  2 +-
 plc4go/internal/bacnetip/Connection.go             |  2 +-
 plc4go/internal/bacnetip/Discoverer.go             |  4 +-
 plc4go/internal/bacnetip/Driver.go                 | 18 +++-----
 plc4go/internal/bacnetip/Reader.go                 |  2 +-
 plc4go/internal/bacnetip/Subscriber.go             |  6 +--
 plc4go/internal/cbus/Reader.go                     |  2 +-
 plc4go/internal/cbus/Subscriber.go                 |  5 ++-
 plc4go/internal/cbus/Writer.go                     |  2 +-
 plc4go/internal/eip/Connection.go                  |  4 +-
 plc4go/internal/eip/Reader.go                      |  2 +-
 plc4go/internal/eip/Writer.go                      |  2 +-
 plc4go/internal/knxnetip/Connection.go             |  6 +--
 .../knxnetip/ConnectionDriverSpecificOperations.go | 14 +++----
 .../knxnetip/ConnectionInternalOperations.go       | 48 +++++++++++-----------
 plc4go/internal/knxnetip/Reader.go                 |  2 +-
 plc4go/internal/knxnetip/Subscriber.go             |  6 +--
 plc4go/internal/knxnetip/Writer.go                 |  2 +-
 plc4go/internal/modbus/Connection.go               |  2 +-
 plc4go/internal/modbus/Reader.go                   |  2 +-
 plc4go/internal/modbus/Writer.go                   |  2 +-
 plc4go/internal/s7/Connection.go                   | 14 +++----
 plc4go/internal/s7/Reader.go                       |  2 +-
 plc4go/internal/s7/Writer.go                       |  2 +-
 plc4go/internal/simulated/Connection.go            |  6 +--
 plc4go/internal/simulated/Reader.go                |  2 +-
 plc4go/internal/simulated/Writer.go                |  2 +-
 plc4go/spi/default/DefaultBrowser.go               |  2 +-
 plc4go/spi/default/DefaultConnection.go            |  4 +-
 plc4go/spi/model/DefaultPlcReadRequest.go          |  2 +-
 plc4go/spi/model/DefaultPlcWriteRequest.go         |  2 +-
 plc4go/spi/utils/Net.go                            |  2 +-
 plc4go/spi/utils/WorkerPool.go                     |  2 +-
 39 files changed, 100 insertions(+), 105 deletions(-)

diff --git a/plc4go/internal/ads/Browser.go b/plc4go/internal/ads/Browser.go
index 1c5862df4b..20e8fdebfd 100644
--- a/plc4go/internal/ads/Browser.go
+++ b/plc4go/internal/ads/Browser.go
@@ -41,7 +41,7 @@ func (m *Connection) Browse(ctx context.Context, browseRequest apiModel.PlcBrows
 }
 
 func (m *Connection) BrowseWithInterceptor(ctx context.Context, browseRequest apiModel.PlcBrowseRequest, interceptor func(result apiModel.PlcBrowseItem) bool) <-chan apiModel.PlcBrowseRequestResult {
-	result := make(chan apiModel.PlcBrowseRequestResult)
+	result := make(chan apiModel.PlcBrowseRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/ads/Connection.go b/plc4go/internal/ads/Connection.go
index c5982d04c1..a03aec00e2 100644
--- a/plc4go/internal/ads/Connection.go
+++ b/plc4go/internal/ads/Connection.go
@@ -97,7 +97,7 @@ func (m *Connection) GetConnection() plc4go.PlcConnection {
 
 func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
 	log.Trace().Msg("Connecting")
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 
 	// Reset the driver context (Actually this should not be required, but just to be on the safe side)
 	m.driverContext.clear()
diff --git a/plc4go/internal/ads/Driver.go b/plc4go/internal/ads/Driver.go
index d102ef24f1..c01f4024c9 100644
--- a/plc4go/internal/ads/Driver.go
+++ b/plc4go/internal/ads/Driver.go
@@ -61,7 +61,7 @@ func (m *Driver) GetConnectionWithContext(ctx context.Context, transportUrl url.
 	transportInstance, err := transport.CreateTransportInstance(transportUrl, options)
 	if err != nil {
 		log.Error().Stringer("transportUrl", &transportUrl).Msgf("We couldn't create a transport instance for port %#v", options["defaultTcpPort"])
-		ch := make(chan plc4go.PlcConnectionConnectResult)
+		ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 		ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.New("couldn't initialize transport configuration for given transport url "+transportUrl.String()))
 		return ch
 	}
@@ -73,7 +73,7 @@ func (m *Driver) GetConnectionWithContext(ctx context.Context, transportUrl url.
 	configuration, err := model.ParseFromOptions(options)
 	if err != nil {
 		log.Error().Err(err).Msgf("Invalid options")
-		ch := make(chan plc4go.PlcConnectionConnectResult)
+		ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 		ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Wrap(err, "invalid configuration"))
 		return ch
 	}
diff --git a/plc4go/internal/ads/Interactions.go b/plc4go/internal/ads/Interactions.go
index bf575f343e..00209ae811 100644
--- a/plc4go/internal/ads/Interactions.go
+++ b/plc4go/internal/ads/Interactions.go
@@ -30,7 +30,7 @@ import (
 )
 
 func (m *Connection) ExecuteAdsReadDeviceInfoRequest(ctx context.Context) (model.AdsReadDeviceInfoResponse, error) {
-	responseChannel := make(chan model.AdsReadDeviceInfoResponse)
+	responseChannel := make(chan model.AdsReadDeviceInfoResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -71,7 +71,7 @@ func (m *Connection) ExecuteAdsReadDeviceInfoRequest(ctx context.Context) (model
 }
 
 func (m *Connection) ExecuteAdsReadRequest(ctx context.Context, indexGroup uint32, indexOffset uint32, length uint32) (model.AdsReadResponse, error) {
-	responseChannel := make(chan model.AdsReadResponse)
+	responseChannel := make(chan model.AdsReadResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -112,7 +112,7 @@ func (m *Connection) ExecuteAdsReadRequest(ctx context.Context, indexGroup uint3
 }
 
 func (m *Connection) ExecuteAdsWriteRequest(ctx context.Context, indexGroup uint32, indexOffset uint32, data []byte) (model.AdsWriteResponse, error) {
-	responseChannel := make(chan model.AdsWriteResponse)
+	responseChannel := make(chan model.AdsWriteResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -153,7 +153,7 @@ func (m *Connection) ExecuteAdsWriteRequest(ctx context.Context, indexGroup uint
 }
 
 func (m *Connection) ExecuteAdsReadWriteRequest(ctx context.Context, indexGroup uint32, indexOffset uint32, readLength uint32, items []model.AdsMultiRequestItem, writeData []byte) (model.AdsReadWriteResponse, error) {
-	responseChannel := make(chan model.AdsReadWriteResponse)
+	responseChannel := make(chan model.AdsReadWriteResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -194,7 +194,7 @@ func (m *Connection) ExecuteAdsReadWriteRequest(ctx context.Context, indexGroup
 }
 
 func (m *Connection) ExecuteAdsAddDeviceNotificationRequest(ctx context.Context, indexGroup uint32, indexOffset uint32, length uint32, transmissionMode model.AdsTransMode, maxDelay uint32, cycleTime uint32) (model.AdsAddDeviceNotificationResponse, error) {
-	responseChannel := make(chan model.AdsAddDeviceNotificationResponse)
+	responseChannel := make(chan model.AdsAddDeviceNotificationResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -235,7 +235,7 @@ func (m *Connection) ExecuteAdsAddDeviceNotificationRequest(ctx context.Context,
 }
 
 func (m *Connection) ExecuteAdsDeleteDeviceNotificationRequest(ctx context.Context, notificationHandle uint32) (model.AdsDeleteDeviceNotificationResponse, error) {
-	responseChannel := make(chan model.AdsDeleteDeviceNotificationResponse)
+	responseChannel := make(chan model.AdsDeleteDeviceNotificationResponse, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/ads/Reader.go b/plc4go/internal/ads/Reader.go
index 2dfdfa461f..4a820729cb 100644
--- a/plc4go/internal/ads/Reader.go
+++ b/plc4go/internal/ads/Reader.go
@@ -42,7 +42,7 @@ func (m *Connection) ReadRequestBuilder() apiModel.PlcReadRequestBuilder {
 
 func (m *Connection) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
 	log.Trace().Msg("Reading")
-	result := make(chan apiModel.PlcReadRequestResult)
+	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/ads/Subscriber.go b/plc4go/internal/ads/Subscriber.go
index 6c899d464d..3a66f23847 100644
--- a/plc4go/internal/ads/Subscriber.go
+++ b/plc4go/internal/ads/Subscriber.go
@@ -97,7 +97,7 @@ func (m *Connection) Subscribe(ctx context.Context, subscriptionRequest apiModel
 	}
 
 	// Create a new result-channel, which completes as soon as all sub-result-channels have returned
-	globalResultChannel := make(chan apiModel.PlcSubscriptionRequestResult)
+	globalResultChannel := make(chan apiModel.PlcSubscriptionRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -126,8 +126,8 @@ func (m *Connection) Subscribe(ctx context.Context, subscriptionRequest apiModel
 }
 
 func (m *Connection) subscribe(ctx context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
-	responseChan := make(chan apiModel.PlcSubscriptionRequestResult)
-	go func(respChan chan apiModel.PlcSubscriptionRequestResult) {
+	responseChan := make(chan apiModel.PlcSubscriptionRequestResult, 1)
+	go func() {
 		defer func() {
 			if err := recover(); err != nil {
 				responseChan <- internalModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.Errorf("panic-ed %v", err))
diff --git a/plc4go/internal/ads/Writer.go b/plc4go/internal/ads/Writer.go
index 423c4e61e1..d2330be112 100644
--- a/plc4go/internal/ads/Writer.go
+++ b/plc4go/internal/ads/Writer.go
@@ -41,7 +41,7 @@ func (m *Connection) WriteRequestBuilder() apiModel.PlcWriteRequestBuilder {
 
 func (m *Connection) Write(ctx context.Context, writeRequest apiModel.PlcWriteRequest) <-chan apiModel.PlcWriteRequestResult {
 	log.Trace().Msg("Writing")
-	result := make(chan apiModel.PlcWriteRequestResult)
+	result := make(chan apiModel.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/bacnetip/Connection.go b/plc4go/internal/bacnetip/Connection.go
index 5967ca1136..2d1cb5c5db 100644
--- a/plc4go/internal/bacnetip/Connection.go
+++ b/plc4go/internal/bacnetip/Connection.go
@@ -78,7 +78,7 @@ func (c *Connection) GetTracer() *spi.Tracer {
 
 func (c *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
 	log.Trace().Msg("Connecting")
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/bacnetip/Discoverer.go b/plc4go/internal/bacnetip/Discoverer.go
index 81c0dba93d..a5f3deb9a1 100644
--- a/plc4go/internal/bacnetip/Discoverer.go
+++ b/plc4go/internal/bacnetip/Discoverer.go
@@ -84,7 +84,7 @@ func (d *Discoverer) Discover(ctx context.Context, callback func(event apiModel.
 }
 
 func broadcastAndDiscover(ctx context.Context, communicationChannels []communicationChannel, specificOptions *protocolSpecificOptions) (chan receivedBvlcMessage, error) {
-	incomingBVLCChannel := make(chan receivedBvlcMessage, 0)
+	incomingBVLCChannel := make(chan receivedBvlcMessage)
 	for _, communicationChannelInstance := range communicationChannels {
 		// Prepare the discovery packet data
 		{
@@ -192,7 +192,7 @@ func broadcastAndDiscover(ctx context.Context, communicationChannels []communica
 
 		go func(communicationChannelInstance communicationChannel) {
 			for {
-				blockingReadChan := make(chan bool, 0)
+				blockingReadChan := make(chan bool)
 				go func() {
 					buf := make([]byte, 4096)
 					n, addr, err := communicationChannelInstance.broadcastConnection.ReadFrom(buf)
diff --git a/plc4go/internal/bacnetip/Driver.go b/plc4go/internal/bacnetip/Driver.go
index afa7fbe606..1315e400c1 100644
--- a/plc4go/internal/bacnetip/Driver.go
+++ b/plc4go/internal/bacnetip/Driver.go
@@ -67,10 +67,8 @@ func (m *Driver) GetConnectionWithContext(ctx context.Context, transportUrl url.
 	transport, ok := transports[transportUrl.Scheme]
 	if !ok {
 		log.Error().Stringer("transportUrl", &transportUrl).Msgf("We couldn't find a transport for scheme %s", transportUrl.Scheme)
-		ch := make(chan plc4go.PlcConnectionConnectResult)
-		go func() {
-			ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Errorf("couldn't find transport for given transport url %#v", transportUrl))
-		}()
+		ch := make(chan plc4go.PlcConnectionConnectResult, 1)
+		ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Errorf("couldn't find transport for given transport url %#v", transportUrl))
 		return ch
 	}
 	// Provide a default-port to the transport, which is used, if the user doesn't provide on in the connection string.
@@ -85,19 +83,15 @@ func (m *Driver) GetConnectionWithContext(ctx context.Context, transportUrl url.
 		udpTransport = transport
 	default:
 		log.Error().Stringer("transportUrl", &transportUrl).Msg("Only udp supported at the moment")
-		ch := make(chan plc4go.PlcConnectionConnectResult)
-		go func() {
-			ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Errorf("couldn't find transport for given transport url %#v", transportUrl))
-		}()
+		ch := make(chan plc4go.PlcConnectionConnectResult, 1)
+		ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Errorf("couldn't find transport for given transport url %#v", transportUrl))
 		return ch
 	}
 
 	codec, err := m.applicationManager.getApplicationLayerMessageCodec(udpTransport, transportUrl, options)
 	if err != nil {
-		ch := make(chan plc4go.PlcConnectionConnectResult)
-		go func() {
-			ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Wrap(err, "error getting application layer message codec"))
-		}()
+		ch := make(chan plc4go.PlcConnectionConnectResult, 1)
+		ch <- _default.NewDefaultPlcConnectionConnectResult(nil, errors.Wrap(err, "error getting application layer message codec"))
 		return ch
 	}
 	log.Debug().Msgf("working with codec %#v", codec)
diff --git a/plc4go/internal/bacnetip/Reader.go b/plc4go/internal/bacnetip/Reader.go
index e67149466d..a1c1e7985a 100644
--- a/plc4go/internal/bacnetip/Reader.go
+++ b/plc4go/internal/bacnetip/Reader.go
@@ -57,7 +57,7 @@ func NewReader(invokeIdGenerator *InvokeIdGenerator, messageCodec spi.MessageCod
 func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
 	// TODO: handle ctx
 	log.Trace().Msg("Reading")
-	result := make(chan apiModel.PlcReadRequestResult)
+	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		if len(readRequest.GetTagNames()) == 0 {
 			result <- &spiModel.DefaultPlcReadRequestResult{
diff --git a/plc4go/internal/bacnetip/Subscriber.go b/plc4go/internal/bacnetip/Subscriber.go
index 4fae04d0fd..b60ea0b60a 100644
--- a/plc4go/internal/bacnetip/Subscriber.go
+++ b/plc4go/internal/bacnetip/Subscriber.go
@@ -40,8 +40,7 @@ func NewSubscriber(connection *Connection) *Subscriber {
 }
 
 func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
-	// TODO: handle ctx
-	result := make(chan apiModel.PlcSubscriptionRequestResult)
+	result := make(chan apiModel.PlcSubscriptionRequestResult, 1)
 	go func() {
 		internalPlcSubscriptionRequest := subscriptionRequest.(*spiModel.DefaultPlcSubscriptionRequest)
 
@@ -67,7 +66,8 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 
 func (m *Subscriber) Unsubscribe(ctx context.Context, unsubscriptionRequest apiModel.PlcUnsubscriptionRequest) <-chan apiModel.PlcUnsubscriptionRequestResult {
 	// TODO: handle ctx
-	result := make(chan apiModel.PlcUnsubscriptionRequestResult)
+	result := make(chan apiModel.PlcUnsubscriptionRequestResult, 1)
+	result <- spiModel.NewDefaultPlcUnsubscriptionRequestResult(unsubscriptionRequest, nil, errors.New("not implemented"))
 
 	// TODO: As soon as we establish a connection, we start getting data...
 	// subscriptions are more an internal handling of which values to pass where.
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index fdb8a4c2ee..c6df55f7cf 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -49,7 +49,7 @@ func NewReader(tpduGenerator *AlphaGenerator, messageCodec *MessageCodec, tm spi
 
 func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
 	log.Trace().Msg("Reading")
-	result := make(chan apiModel.PlcReadRequestResult)
+	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go m.readSync(ctx, readRequest, result)
 	return result
 }
diff --git a/plc4go/internal/cbus/Subscriber.go b/plc4go/internal/cbus/Subscriber.go
index aa1794f472..f1c72fa747 100644
--- a/plc4go/internal/cbus/Subscriber.go
+++ b/plc4go/internal/cbus/Subscriber.go
@@ -47,7 +47,7 @@ func NewSubscriber(connection *Connection) *Subscriber {
 }
 
 func (m *Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
-	result := make(chan apiModel.PlcSubscriptionRequestResult)
+	result := make(chan apiModel.PlcSubscriptionRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -78,7 +78,8 @@ func (m *Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.P
 
 func (m *Subscriber) Unsubscribe(ctx context.Context, unsubscriptionRequest apiModel.PlcUnsubscriptionRequest) <-chan apiModel.PlcUnsubscriptionRequestResult {
 	// TODO: handle context
-	result := make(chan apiModel.PlcUnsubscriptionRequestResult)
+	result := make(chan apiModel.PlcUnsubscriptionRequestResult, 1)
+	result <- spiModel.NewDefaultPlcUnsubscriptionRequestResult(unsubscriptionRequest, nil, errors.New("Not Implemented"))
 
 	// TODO: As soon as we establish a connection, we start getting data...
 	// subscriptions are more a internal handling of which values to pass where.
diff --git a/plc4go/internal/cbus/Writer.go b/plc4go/internal/cbus/Writer.go
index 47d15cc258..1808d03cf7 100644
--- a/plc4go/internal/cbus/Writer.go
+++ b/plc4go/internal/cbus/Writer.go
@@ -48,7 +48,7 @@ func NewWriter(tpduGenerator *AlphaGenerator, messageCodec *MessageCodec, tm spi
 
 func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteRequest) <-chan apiModel.PlcWriteRequestResult {
 	log.Trace().Msg("Writing")
-	result := make(chan apiModel.PlcWriteRequestResult)
+	result := make(chan apiModel.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/eip/Connection.go b/plc4go/internal/eip/Connection.go
index 9bdd960ca8..242d143a83 100644
--- a/plc4go/internal/eip/Connection.go
+++ b/plc4go/internal/eip/Connection.go
@@ -104,7 +104,7 @@ func (m *Connection) GetMessageCodec() spi.MessageCodec {
 
 func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
 	log.Trace().Msg("Connecting")
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -135,7 +135,7 @@ func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcCo
 func (m *Connection) Close() <-chan plc4go.PlcConnectionCloseResult {
 	// TODO: use proper context
 	ctx := context.TODO()
-	result := make(chan plc4go.PlcConnectionCloseResult)
+	result := make(chan plc4go.PlcConnectionCloseResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/eip/Reader.go b/plc4go/internal/eip/Reader.go
index 1ce0e914b4..b6f5576310 100644
--- a/plc4go/internal/eip/Reader.go
+++ b/plc4go/internal/eip/Reader.go
@@ -58,7 +58,7 @@ func NewReader(messageCodec spi.MessageCodec, tm spi.RequestTransactionManager,
 func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
 	// TODO: handle ctx
 	log.Trace().Msg("Reading")
-	result := make(chan apiModel.PlcReadRequestResult)
+	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/eip/Writer.go b/plc4go/internal/eip/Writer.go
index b37457d6b1..8636a8d1d4 100644
--- a/plc4go/internal/eip/Writer.go
+++ b/plc4go/internal/eip/Writer.go
@@ -55,7 +55,7 @@ func NewWriter(messageCodec spi.MessageCodec, tm spi.RequestTransactionManager,
 
 func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <-chan model.PlcWriteRequestResult {
 	// TODO: handle context
-	result := make(chan model.PlcWriteRequestResult)
+	result := make(chan model.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/knxnetip/Connection.go b/plc4go/internal/knxnetip/Connection.go
index 5191371c83..51c04f6b09 100644
--- a/plc4go/internal/knxnetip/Connection.go
+++ b/plc4go/internal/knxnetip/Connection.go
@@ -221,7 +221,7 @@ func (m *Connection) Connect() <-chan plc4go.PlcConnectionConnectResult {
 }
 
 func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
-	result := make(chan plc4go.PlcConnectionConnectResult)
+	result := make(chan plc4go.PlcConnectionConnectResult, 1)
 	sendResult := func(connection plc4go.PlcConnection, err error) {
 		result <- _default.NewDefaultPlcConnectionConnectResult(connection, err)
 	}
@@ -396,7 +396,7 @@ func (m *Connection) BlockingClose() {
 func (m *Connection) Close() <-chan plc4go.PlcConnectionCloseResult {
 	// TODO: use proper context
 	ctx := context.TODO()
-	result := make(chan plc4go.PlcConnectionCloseResult)
+	result := make(chan plc4go.PlcConnectionCloseResult, 1)
 
 	go func() {
 		defer func() {
@@ -459,7 +459,7 @@ func (m *Connection) IsConnected() bool {
 func (m *Connection) Ping() <-chan plc4go.PlcConnectionPingResult {
 	// TODO: use proper context
 	ctx := context.TODO()
-	result := make(chan plc4go.PlcConnectionPingResult)
+	result := make(chan plc4go.PlcConnectionPingResult, 1)
 
 	go func() {
 		defer func() {
diff --git a/plc4go/internal/knxnetip/ConnectionDriverSpecificOperations.go b/plc4go/internal/knxnetip/ConnectionDriverSpecificOperations.go
index 1b7ac49b50..5e551225eb 100644
--- a/plc4go/internal/knxnetip/ConnectionDriverSpecificOperations.go
+++ b/plc4go/internal/knxnetip/ConnectionDriverSpecificOperations.go
@@ -45,7 +45,7 @@ import (
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 func (m *Connection) ReadGroupAddress(ctx context.Context, groupAddress []byte, datapointType *driverModel.KnxDatapointType) <-chan KnxReadResult {
-	result := make(chan KnxReadResult)
+	result := make(chan KnxReadResult, 1)
 
 	sendResponse := func(value values.PlcValue, numItems uint8, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -106,7 +106,7 @@ func (m *Connection) ReadGroupAddress(ctx context.Context, groupAddress []byte,
 }
 
 func (m *Connection) DeviceConnect(ctx context.Context, targetAddress driverModel.KnxAddress) <-chan KnxDeviceConnectResult {
-	result := make(chan KnxDeviceConnectResult)
+	result := make(chan KnxDeviceConnectResult, 1)
 
 	sendResponse := func(connection *KnxDeviceConnection, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -201,7 +201,7 @@ func (m *Connection) DeviceConnect(ctx context.Context, targetAddress driverMode
 }
 
 func (m *Connection) DeviceDisconnect(ctx context.Context, targetAddress driverModel.KnxAddress) <-chan KnxDeviceDisconnectResult {
-	result := make(chan KnxDeviceDisconnectResult)
+	result := make(chan KnxDeviceDisconnectResult, 1)
 
 	sendResponse := func(connection *KnxDeviceConnection, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -240,7 +240,7 @@ func (m *Connection) DeviceDisconnect(ctx context.Context, targetAddress driverM
 }
 
 func (m *Connection) DeviceAuthenticate(ctx context.Context, targetAddress driverModel.KnxAddress, buildingKey []byte) <-chan KnxDeviceAuthenticateResult {
-	result := make(chan KnxDeviceAuthenticateResult)
+	result := make(chan KnxDeviceAuthenticateResult, 1)
 
 	sendResponse := func(err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -298,7 +298,7 @@ func (m *Connection) DeviceAuthenticate(ctx context.Context, targetAddress drive
 }
 
 func (m *Connection) DeviceReadProperty(ctx context.Context, targetAddress driverModel.KnxAddress, objectId uint8, propertyId uint8, propertyIndex uint16, numElements uint8) <-chan KnxReadResult {
-	result := make(chan KnxReadResult)
+	result := make(chan KnxReadResult, 1)
 
 	sendResponse := func(value values.PlcValue, numItems uint8, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -382,7 +382,7 @@ func (m *Connection) DeviceReadProperty(ctx context.Context, targetAddress drive
 }
 
 func (m *Connection) DeviceReadPropertyDescriptor(ctx context.Context, targetAddress driverModel.KnxAddress, objectId uint8, propertyId uint8) <-chan KnxReadResult {
-	result := make(chan KnxReadResult)
+	result := make(chan KnxReadResult, 1)
 
 	sendResponse := func(value values.PlcValue, numItems uint8, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
@@ -447,7 +447,7 @@ func (m *Connection) DeviceReadPropertyDescriptor(ctx context.Context, targetAdd
 }
 
 func (m *Connection) DeviceReadMemory(ctx context.Context, targetAddress driverModel.KnxAddress, address uint16, numElements uint8, datapointType *driverModel.KnxDatapointType) <-chan KnxReadResult {
-	result := make(chan KnxReadResult)
+	result := make(chan KnxReadResult, 1)
 
 	sendResponse := func(value values.PlcValue, numItems uint8, err error) {
 		timeout := time.NewTimer(time.Millisecond * 10)
diff --git a/plc4go/internal/knxnetip/ConnectionInternalOperations.go b/plc4go/internal/knxnetip/ConnectionInternalOperations.go
index 027b42505b..1419603638 100644
--- a/plc4go/internal/knxnetip/ConnectionInternalOperations.go
+++ b/plc4go/internal/knxnetip/ConnectionInternalOperations.go
@@ -54,8 +54,8 @@ func (m *Connection) sendGatewaySearchRequest(ctx context.Context) (driverModel.
 	)
 	searchRequest := driverModel.NewSearchRequest(discoveryEndpoint)
 
-	result := make(chan driverModel.SearchResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.SearchResponse, 1)
+	errorResult := make(chan error, 1)
 	err = m.messageCodec.SendRequest(ctx, searchRequest,
 		func(message spi.Message) bool {
 			_, ok := message.(driverModel.SearchResponseExactly)
@@ -112,8 +112,8 @@ func (m *Connection) sendGatewayConnectionRequest(ctx context.Context) (driverMo
 		driverModel.NewConnectionRequestInformationTunnelConnection(driverModel.KnxLayer_TUNNEL_LINK_LAYER),
 	)
 
-	result := make(chan driverModel.ConnectionResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ConnectionResponse, 1)
+	errorResult := make(chan error, 1)
 	err = m.messageCodec.SendRequest(ctx, connectionRequest,
 		func(message spi.Message) bool {
 			_, ok := message.(driverModel.ConnectionResponseExactly)
@@ -162,8 +162,8 @@ func (m *Connection) sendGatewayDisconnectionRequest(ctx context.Context) (drive
 		),
 	)
 
-	result := make(chan driverModel.DisconnectResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.DisconnectResponse, 1)
+	errorResult := make(chan error, 1)
 	err = m.messageCodec.SendRequest(ctx, disconnectRequest,
 		func(message spi.Message) bool {
 			_, ok := message.(driverModel.DisconnectResponseExactly)
@@ -210,8 +210,8 @@ func (m *Connection) sendConnectionStateRequest(ctx context.Context) (driverMode
 			driverModel.HostProtocolCode_IPV4_UDP,
 			localAddr, uint16(localAddress.Port)))
 
-	result := make(chan driverModel.ConnectionStateResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ConnectionStateResponse, 1)
+	errorResult := make(chan error, 1)
 	err = m.messageCodec.SendRequest(ctx, connectionStateRequest,
 		func(message spi.Message) bool {
 			_, ok := message.(driverModel.ConnectionStateResponseExactly)
@@ -269,8 +269,8 @@ func (m *Connection) sendGroupAddressReadRequest(ctx context.Context, groupAddre
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataGroupValueResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataGroupValueResponse, 1)
+	errorResult := make(chan error, 1)
 	err := m.messageCodec.SendRequest(ctx, groupAddressReadRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -353,8 +353,8 @@ func (m *Connection) sendDeviceConnectionRequest(ctx context.Context, targetAddr
 		0,
 	)
 
-	result := make(chan driverModel.ApduControlConnect)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduControlConnect, 1)
+	errorResult := make(chan error, 1)
 	err := m.messageCodec.SendRequest(ctx, deviceConnectionRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -443,8 +443,8 @@ func (m *Connection) sendDeviceDisconnectionRequest(ctx context.Context, targetA
 		0,
 	)
 
-	result := make(chan driverModel.ApduControlDisconnect)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduControlDisconnect, 1)
+	errorResult := make(chan error, 1)
 	if err := m.messageCodec.SendRequest(ctx, deviceDisconnectionRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -549,8 +549,8 @@ func (m *Connection) sendDeviceAuthentication(ctx context.Context, targetAddress
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataExtAuthorizeResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataExtAuthorizeResponse, 1)
+	errorResult := make(chan error, 1)
 	if err := m.messageCodec.SendRequest(ctx, deviceAuthenticationRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -660,8 +660,8 @@ func (m *Connection) sendDeviceDeviceDescriptorReadRequest(ctx context.Context,
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataDeviceDescriptorResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataDeviceDescriptorResponse, 1)
+	errorResult := make(chan error, 1)
 	err := m.messageCodec.SendRequest(ctx, deviceDescriptorReadRequest, func(message spi.Message) bool {
 		tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
 		if !ok || tunnelingRequest.GetTunnelingRequestDataBlock().GetCommunicationChannelId() != m.CommunicationChannelId {
@@ -768,8 +768,8 @@ func (m *Connection) sendDevicePropertyReadRequest(ctx context.Context, targetAd
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataExtPropertyValueResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataExtPropertyValueResponse, 1)
+	errorResult := make(chan error, 1)
 	if err := m.messageCodec.SendRequest(ctx, propertyReadRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -884,8 +884,8 @@ func (m *Connection) sendDevicePropertyDescriptionReadRequest(ctx context.Contex
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataExtPropertyDescriptionResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataExtPropertyDescriptionResponse, 1)
+	errorResult := make(chan error, 1)
 	err := m.messageCodec.SendRequest(ctx, propertyReadRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
@@ -997,8 +997,8 @@ func (m *Connection) sendDeviceMemoryReadRequest(ctx context.Context, targetAddr
 		0,
 	)
 
-	result := make(chan driverModel.ApduDataMemoryResponse)
-	errorResult := make(chan error)
+	result := make(chan driverModel.ApduDataMemoryResponse, 1)
+	errorResult := make(chan error, 1)
 	if err := m.messageCodec.SendRequest(ctx, propertyReadRequest,
 		func(message spi.Message) bool {
 			tunnelingRequest, ok := message.(driverModel.TunnelingRequestExactly)
diff --git a/plc4go/internal/knxnetip/Reader.go b/plc4go/internal/knxnetip/Reader.go
index 27c635a004..e3f22f7b2d 100644
--- a/plc4go/internal/knxnetip/Reader.go
+++ b/plc4go/internal/knxnetip/Reader.go
@@ -48,7 +48,7 @@ func NewReader(connection *Connection) *Reader {
 
 func (m Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <-chan apiModel.PlcReadRequestResult {
 	// TODO: handle ctx
-	resultChan := make(chan apiModel.PlcReadRequestResult)
+	resultChan := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/knxnetip/Subscriber.go b/plc4go/internal/knxnetip/Subscriber.go
index 33fc2c762f..7355e7e544 100644
--- a/plc4go/internal/knxnetip/Subscriber.go
+++ b/plc4go/internal/knxnetip/Subscriber.go
@@ -46,7 +46,7 @@ func NewSubscriber(connection *Connection) *Subscriber {
 
 func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
 	// TODO: handle context
-	result := make(chan apiModel.PlcSubscriptionRequestResult)
+	result := make(chan apiModel.PlcSubscriptionRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -78,8 +78,8 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 
 func (m *Subscriber) Unsubscribe(ctx context.Context, unsubscriptionRequest apiModel.PlcUnsubscriptionRequest) <-chan apiModel.PlcUnsubscriptionRequestResult {
 	// TODO: handle context
-	result := make(chan apiModel.PlcUnsubscriptionRequestResult)
-
+	result := make(chan apiModel.PlcUnsubscriptionRequestResult, 1)
+	result <- spiModel.NewDefaultPlcUnsubscriptionRequestResult(unsubscriptionRequest, nil, errors.New("Not Implemented"))
 	// TODO: As soon as we establish a connection, we start getting data...
 	// subscriptions are more an internal handling of which values to pass where.
 
diff --git a/plc4go/internal/knxnetip/Writer.go b/plc4go/internal/knxnetip/Writer.go
index cdd10eec53..2ee56238e2 100644
--- a/plc4go/internal/knxnetip/Writer.go
+++ b/plc4go/internal/knxnetip/Writer.go
@@ -41,7 +41,7 @@ func NewWriter(messageCodec spi.MessageCodec) Writer {
 
 func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <-chan model.PlcWriteRequestResult {
 	// TODO: handle context
-	result := make(chan model.PlcWriteRequestResult)
+	result := make(chan model.PlcWriteRequestResult, 1)
 	// If we are requesting only one tag, use a
 	if len(writeRequest.GetTagNames()) == 1 {
 		tagName := writeRequest.GetTagNames()[0]
diff --git a/plc4go/internal/modbus/Connection.go b/plc4go/internal/modbus/Connection.go
index 476ec7cf56..97afeaa7d0 100644
--- a/plc4go/internal/modbus/Connection.go
+++ b/plc4go/internal/modbus/Connection.go
@@ -96,7 +96,7 @@ func (m *Connection) Ping() <-chan plc4go.PlcConnectionPingResult {
 	// TODO: use proper context
 	ctx := context.TODO()
 	log.Trace().Msg("Pinging")
-	result := make(chan plc4go.PlcConnectionPingResult)
+	result := make(chan plc4go.PlcConnectionPingResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/modbus/Reader.go b/plc4go/internal/modbus/Reader.go
index d0914a4730..cac63f0b7e 100644
--- a/plc4go/internal/modbus/Reader.go
+++ b/plc4go/internal/modbus/Reader.go
@@ -51,7 +51,7 @@ func NewReader(unitIdentifier uint8, messageCodec spi.MessageCodec) *Reader {
 func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-chan model.PlcReadRequestResult {
 	// TODO: handle ctx
 	log.Trace().Msg("Reading")
-	result := make(chan model.PlcReadRequestResult)
+	result := make(chan model.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/modbus/Writer.go b/plc4go/internal/modbus/Writer.go
index d13bcf38a8..73251d2187 100644
--- a/plc4go/internal/modbus/Writer.go
+++ b/plc4go/internal/modbus/Writer.go
@@ -49,7 +49,7 @@ func NewWriter(unitIdentifier uint8, messageCodec spi.MessageCodec) Writer {
 
 func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <-chan model.PlcWriteRequestResult {
 	// TODO: handle context
-	result := make(chan model.PlcWriteRequestResult)
+	result := make(chan model.PlcWriteRequestResult, 1)
 	go func() {
 		// If we are requesting only one tag, use a
 		if len(writeRequest.GetTagNames()) != 1 {
diff --git a/plc4go/internal/s7/Connection.go b/plc4go/internal/s7/Connection.go
index 8e1ab6870d..e980e7bbed 100644
--- a/plc4go/internal/s7/Connection.go
+++ b/plc4go/internal/s7/Connection.go
@@ -108,7 +108,7 @@ func (m *Connection) GetMessageCodec() spi.MessageCodec {
 
 func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
 	log.Trace().Msg("Connecting")
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -149,8 +149,8 @@ func (m *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcCo
 func (m *Connection) setupConnection(ctx context.Context, ch chan plc4go.PlcConnectionConnectResult) {
 	log.Debug().Msg("Sending COTP Connection Request")
 	// Open the session on ISO Transport Protocol first.
-	cotpConnectionResult := make(chan readWriteModel.COTPPacketConnectionResponse)
-	cotpConnectionErrorChan := make(chan error)
+	cotpConnectionResult := make(chan readWriteModel.COTPPacketConnectionResponse, 1)
+	cotpConnectionErrorChan := make(chan error, 1)
 	if err := m.messageCodec.SendRequest(ctx, readWriteModel.NewTPKTPacket(m.createCOTPConnectionRequest()), func(message spi.Message) bool {
 		tpktPacket := message.(readWriteModel.TPKTPacket)
 		if tpktPacket == nil {
@@ -180,8 +180,8 @@ func (m *Connection) setupConnection(ctx context.Context, ch chan plc4go.PlcConn
 		log.Debug().Msg("Sending S7 Connection Request")
 
 		// Send an S7 login message.
-		s7ConnectionResult := make(chan readWriteModel.S7ParameterSetupCommunication)
-		s7ConnectionErrorChan := make(chan error)
+		s7ConnectionResult := make(chan readWriteModel.S7ParameterSetupCommunication, 1)
+		s7ConnectionErrorChan := make(chan error, 1)
 		if err := m.messageCodec.SendRequest(ctx, m.createS7ConnectionRequest(cotpPacketConnectionResponse), func(message spi.Message) bool {
 			tpktPacket, ok := message.(readWriteModel.TPKTPacketExactly)
 			if !ok {
@@ -241,8 +241,8 @@ func (m *Connection) setupConnection(ctx context.Context, ch chan plc4go.PlcConn
 
 			// Prepare a message to request the remote to identify itself.
 			log.Debug().Msg("Sending S7 Identification Request")
-			s7IdentificationResult := make(chan readWriteModel.S7PayloadUserData)
-			s7IdentificationErrorChan := make(chan error)
+			s7IdentificationResult := make(chan readWriteModel.S7PayloadUserData, 1)
+			s7IdentificationErrorChan := make(chan error, 1)
 			if err := m.messageCodec.SendRequest(ctx, m.createIdentifyRemoteMessage(), func(message spi.Message) bool {
 				tpktPacket, ok := message.(readWriteModel.TPKTPacketExactly)
 				if !ok {
diff --git a/plc4go/internal/s7/Reader.go b/plc4go/internal/s7/Reader.go
index 7b6226cdb9..8b327f973e 100644
--- a/plc4go/internal/s7/Reader.go
+++ b/plc4go/internal/s7/Reader.go
@@ -50,7 +50,7 @@ func NewReader(tpduGenerator *TpduGenerator, messageCodec spi.MessageCodec, tm s
 func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-chan model.PlcReadRequestResult {
 	// TODO: handle ctx
 	log.Trace().Msg("Reading")
-	result := make(chan model.PlcReadRequestResult)
+	result := make(chan model.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/s7/Writer.go b/plc4go/internal/s7/Writer.go
index 7053daa9b5..b9a1773c48 100644
--- a/plc4go/internal/s7/Writer.go
+++ b/plc4go/internal/s7/Writer.go
@@ -48,7 +48,7 @@ func NewWriter(tpduGenerator *TpduGenerator, messageCodec spi.MessageCodec, tm s
 
 func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <-chan model.PlcWriteRequestResult {
 	// TODO: handle context
-	result := make(chan model.PlcWriteRequestResult)
+	result := make(chan model.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/simulated/Connection.go b/plc4go/internal/simulated/Connection.go
index 95e4c35015..371303a1c5 100644
--- a/plc4go/internal/simulated/Connection.go
+++ b/plc4go/internal/simulated/Connection.go
@@ -78,7 +78,7 @@ func (c *Connection) Connect() <-chan plc4go.PlcConnectionConnectResult {
 }
 
 func (c *Connection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -134,7 +134,7 @@ func (c *Connection) BlockingClose() {
 }
 
 func (c *Connection) Close() <-chan plc4go.PlcConnectionCloseResult {
-	ch := make(chan plc4go.PlcConnectionCloseResult)
+	ch := make(chan plc4go.PlcConnectionCloseResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -180,7 +180,7 @@ func (c *Connection) IsConnected() bool {
 }
 
 func (c *Connection) Ping() <-chan plc4go.PlcConnectionPingResult {
-	ch := make(chan plc4go.PlcConnectionPingResult)
+	ch := make(chan plc4go.PlcConnectionPingResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/simulated/Reader.go b/plc4go/internal/simulated/Reader.go
index ea3e2fcda9..cdb77f7350 100644
--- a/plc4go/internal/simulated/Reader.go
+++ b/plc4go/internal/simulated/Reader.go
@@ -46,7 +46,7 @@ func NewReader(device *Device, options map[string][]string, tracer *spi.Tracer)
 }
 
 func (r *Reader) Read(_ context.Context, readRequest model.PlcReadRequest) <-chan model.PlcReadRequestResult {
-	ch := make(chan model.PlcReadRequestResult)
+	ch := make(chan model.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/internal/simulated/Writer.go b/plc4go/internal/simulated/Writer.go
index b8cae999ad..0c2cd25447 100644
--- a/plc4go/internal/simulated/Writer.go
+++ b/plc4go/internal/simulated/Writer.go
@@ -45,7 +45,7 @@ func NewWriter(device *Device, options map[string][]string, tracer *spi.Tracer)
 }
 
 func (w *Writer) Write(_ context.Context, writeRequest model.PlcWriteRequest) <-chan model.PlcWriteRequestResult {
-	ch := make(chan model.PlcWriteRequestResult)
+	ch := make(chan model.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/spi/default/DefaultBrowser.go b/plc4go/spi/default/DefaultBrowser.go
index ab7a628f48..4688d0aaf1 100644
--- a/plc4go/spi/default/DefaultBrowser.go
+++ b/plc4go/spi/default/DefaultBrowser.go
@@ -66,7 +66,7 @@ func (m *defaultBrowser) Browse(ctx context.Context, browseRequest apiModel.PlcB
 }
 
 func (m *defaultBrowser) BrowseWithInterceptor(ctx context.Context, browseRequest apiModel.PlcBrowseRequest, interceptor func(result apiModel.PlcBrowseItem) bool) <-chan apiModel.PlcBrowseRequestResult {
-	result := make(chan apiModel.PlcBrowseRequestResult)
+	result := make(chan apiModel.PlcBrowseRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/spi/default/DefaultConnection.go b/plc4go/spi/default/DefaultConnection.go
index c0505bcea4..2a8c58656a 100644
--- a/plc4go/spi/default/DefaultConnection.go
+++ b/plc4go/spi/default/DefaultConnection.go
@@ -234,7 +234,7 @@ func (d *defaultConnection) Connect() <-chan plc4go.PlcConnectionConnectResult {
 
 func (d *defaultConnection) ConnectWithContext(ctx context.Context) <-chan plc4go.PlcConnectionConnectResult {
 	log.Trace().Msg("Connecting")
-	ch := make(chan plc4go.PlcConnectionConnectResult)
+	ch := make(chan plc4go.PlcConnectionConnectResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
@@ -284,7 +284,7 @@ func (d *defaultConnection) IsConnected() bool {
 }
 
 func (d *defaultConnection) Ping() <-chan plc4go.PlcConnectionPingResult {
-	ch := make(chan plc4go.PlcConnectionPingResult)
+	ch := make(chan plc4go.PlcConnectionPingResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/spi/model/DefaultPlcReadRequest.go b/plc4go/spi/model/DefaultPlcReadRequest.go
index 67775e8c9f..23653e5acb 100644
--- a/plc4go/spi/model/DefaultPlcReadRequest.go
+++ b/plc4go/spi/model/DefaultPlcReadRequest.go
@@ -136,7 +136,7 @@ func (d *DefaultPlcReadRequest) ExecuteWithContext(ctx context.Context) <-chan a
 	}
 
 	// Create a new result-channel, which completes as soon as all sub-result-channels have returned
-	resultChannel := make(chan apiModel.PlcReadRequestResult)
+	resultChannel := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/spi/model/DefaultPlcWriteRequest.go b/plc4go/spi/model/DefaultPlcWriteRequest.go
index 9e846e10d0..c0146e0e83 100644
--- a/plc4go/spi/model/DefaultPlcWriteRequest.go
+++ b/plc4go/spi/model/DefaultPlcWriteRequest.go
@@ -155,7 +155,7 @@ func (d *DefaultPlcWriteRequest) ExecuteWithContext(ctx context.Context) <-chan
 	}
 
 	// Create a new result-channel, which completes as soon as all sub-result-channels have returned
-	resultChannel := make(chan apiModel.PlcWriteRequestResult)
+	resultChannel := make(chan apiModel.PlcWriteRequestResult, 1)
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
diff --git a/plc4go/spi/utils/Net.go b/plc4go/spi/utils/Net.go
index 59b41e1ad0..a2a6e539be 100644
--- a/plc4go/spi/utils/Net.go
+++ b/plc4go/spi/utils/Net.go
@@ -120,7 +120,7 @@ func lockupIpsUsingArp(ctx context.Context, netInterface net.Interface, ipNet *n
 	}
 
 	// Start up a goroutine to read in packet data.
-	stop := make(chan struct{})
+	stop := make(chan struct{}, 1)
 	// As we don't know how much the handler will find we use a value of 1 and set that to done after the 10 sec in the cleanup function directly after
 	wg.Add(1)
 	// Handler for processing incoming ARP responses.
diff --git a/plc4go/spi/utils/WorkerPool.go b/plc4go/spi/utils/WorkerPool.go
index a2247065e9..a1d8202a7c 100644
--- a/plc4go/spi/utils/WorkerPool.go
+++ b/plc4go/spi/utils/WorkerPool.go
@@ -46,7 +46,7 @@ type worker struct {
 func (w *worker) initialize() {
 	w.shutdown.Store(false)
 	w.interrupted.Store(false)
-	w.interrupter = make(chan struct{})
+	w.interrupter = make(chan struct{}, 1)
 	w.hasEnded.Store(false)
 	w.lastReceived = time.Now()
 }


[plc4x] 02/02: refactor(plc4go): use constructors when possible for default types

Posted by sr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit e9d689fad485298b3f978f2c313dd15bbda8a95d
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon May 15 18:05:32 2023 +0200

    refactor(plc4go): use constructors when possible for default types
---
 plc4go/internal/ads/Browser.go            | 30 +++++-------
 plc4go/internal/ads/Discoverer.go         | 16 +++----
 plc4go/internal/ads/Reader.go             | 79 ++++++++++++++++---------------
 plc4go/internal/ads/Subscriber.go         | 41 ++++++++--------
 plc4go/internal/ads/Writer.go             | 76 +++++++----------------------
 plc4go/internal/bacnetip/Discoverer.go    | 30 +++++++-----
 plc4go/internal/bacnetip/Reader.go        | 43 ++++++++---------
 plc4go/internal/bacnetip/Subscriber.go    | 12 ++---
 plc4go/internal/cbus/Browser.go           | 18 +++----
 plc4go/internal/cbus/Discoverer.go        | 15 +++---
 plc4go/internal/cbus/Reader.go            | 32 ++++++-------
 plc4go/internal/cbus/Subscriber.go        | 10 ++--
 plc4go/internal/cbus/Writer.go            | 40 +++++++---------
 plc4go/internal/eip/Reader.go             | 37 ++++++++-------
 plc4go/internal/eip/Writer.go             | 24 ++--------
 plc4go/internal/knxnetip/Browser.go       | 47 +++++++++++-------
 plc4go/internal/knxnetip/Discoverer.go    | 15 +++---
 plc4go/internal/knxnetip/Reader.go        | 10 ++--
 plc4go/internal/knxnetip/Subscriber.go    | 10 ++--
 plc4go/internal/knxnetip/Writer.go        | 12 +----
 plc4go/internal/modbus/Reader.go          | 67 +++++++++++++-------------
 plc4go/internal/modbus/Writer.go          | 22 +++------
 plc4go/internal/s7/Reader.go              | 47 +++++++++---------
 plc4go/internal/s7/Writer.go              | 18 ++-----
 plc4go/internal/simulated/Reader.go       | 10 ++--
 plc4go/internal/simulated/Subscriber.go   | 12 ++++-
 plc4go/internal/simulated/Writer.go       |  6 +--
 plc4go/spi/default/DefaultBrowser.go      | 10 ++--
 plc4go/spi/model/DefaultPlcReadRequest.go |  2 +-
 29 files changed, 363 insertions(+), 428 deletions(-)

diff --git a/plc4go/internal/ads/Browser.go b/plc4go/internal/ads/Browser.go
index 20e8fdebfd..aa0aa720e2 100644
--- a/plc4go/internal/ads/Browser.go
+++ b/plc4go/internal/ads/Browser.go
@@ -45,10 +45,7 @@ func (m *Connection) BrowseWithInterceptor(ctx context.Context, browseRequest ap
 	go func() {
 		defer func() {
 			if err := recover(); err != nil {
-				result <- &internalModel.DefaultPlcBrowseRequestResult{
-					Request: browseRequest,
-					Err:     errors.Errorf("Recovered from panic: %v", err),
-				}
+				result <- internalModel.NewDefaultPlcBrowseRequestResult(browseRequest, nil, errors.Errorf("Recovered from panic: %v", err))
 			}
 		}()
 		responseCodes := map[string]apiModel.PlcResponseCode{}
@@ -58,11 +55,7 @@ func (m *Connection) BrowseWithInterceptor(ctx context.Context, browseRequest ap
 			responseCodes[queryName], results[queryName] = m.BrowseQuery(ctx, interceptor, queryName, query)
 		}
 		browseResponse := internalModel.NewDefaultPlcBrowseResponse(browseRequest, results, responseCodes)
-		result <- &internalModel.DefaultPlcBrowseRequestResult{
-			Request:  browseRequest,
-			Response: browseResponse,
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcBrowseRequestResult(browseRequest, browseResponse, nil)
 	}()
 	return result
 }
@@ -122,20 +115,21 @@ func (m *Connection) filterDataTypes(parentName string, currentType driverModel.
 				UpperBound: ai.GetUpperBound(),
 			})
 		}
-		foundTag := &internalModel.DefaultPlcBrowseItem{
-			Tag: model.SymbolicPlcTag{
+		foundTag := internalModel.NewDefaultPlcBrowseItem(
+			model.SymbolicPlcTag{
 				PlcTag: model.PlcTag{
 					ArrayInfo: arrayInfo,
 				},
 				SymbolicAddress: parentName,
 			},
-			Name:         parentName,
-			DataTypeName: currentType.GetDataTypeName(),
-			Readable:     false,
-			Writable:     false,
-			Subscribable: false,
-			Options:      nil,
-		}
+			parentName,
+			currentType.GetDataTypeName(),
+			false,
+			false,
+			false,
+			nil,
+			nil,
+		)
 		return []apiModel.PlcBrowseItem{foundTag}
 	}
 
diff --git a/plc4go/internal/ads/Discoverer.go b/plc4go/internal/ads/Discoverer.go
index f54927fedd..b9d6606202 100644
--- a/plc4go/internal/ads/Discoverer.go
+++ b/plc4go/internal/ads/Discoverer.go
@@ -218,14 +218,14 @@ func (d *Discoverer) Discover(ctx context.Context, callback func(event apiModel.
 					strconv.Itoa(int(remoteAmsNetId.GetOctet4())) + ":" +
 					strconv.Itoa(int(driverModel.AdsConstants_ADSTCPDEFAULTPORT)))
 				if err2 == nil {
-					plcDiscoveryItem := &internalModel.DefaultPlcDiscoveryItem{
-						ProtocolCode:  "ads",
-						TransportCode: "tcp",
-						TransportUrl:  *remoteAddress,
-						Options:       opts,
-						Name:          hostNameBlock.GetHostName().GetText(),
-						Attributes:    attributes,
-					}
+					plcDiscoveryItem := internalModel.NewDefaultPlcDiscoveryItem(
+						"ads",
+						"tcp",
+						*remoteAddress,
+						opts,
+						hostNameBlock.GetHostName().GetText(),
+						attributes,
+					)
 
 					// Pass the event back to the callback
 					callback(plcDiscoveryItem)
diff --git a/plc4go/internal/ads/Reader.go b/plc4go/internal/ads/Reader.go
index 4a820729cb..ce28c0e2f9 100644
--- a/plc4go/internal/ads/Reader.go
+++ b/plc4go/internal/ads/Reader.go
@@ -78,11 +78,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 		// Replace the symbolic tag with a direct one
 		tag, err = m.resolveSymbolicTag(ctx, adsField)
 		if err != nil {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -102,10 +102,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 		}()
 		response, err := m.ExecuteAdsReadRequest(ctx, directAdsTag.IndexGroup, directAdsTag.IndexOffset, directAdsTag.DataType.GetSize())
 		if err != nil {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrap(err, "got error executing the read request"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "got error executing the read request"),
+			)
 			return
 		}
 
@@ -129,11 +130,11 @@ func (m *Connection) singleRead(ctx context.Context, readRequest apiModel.PlcRea
 			}
 		}
 		// Return the response to the caller.
-		result <- &internalModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
+			nil,
+		)
 	}()
 }
 
@@ -148,33 +149,33 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 		if model.NeedsResolving(tag) {
 			adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 			if err != nil {
-				result <- &internalModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "invalid tag item type"),
+				)
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 			// Replace the symbolic tag with a direct one
 			tag, err = m.resolveSymbolicTag(ctx, adsField)
 			if err != nil {
-				result <- &internalModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "invalid tag item type"),
+				)
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 		}
 		directAdsTag, ok := tag.(*model.DirectPlcTag)
 		if !ok {
-			result <- &internalModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.New("invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -201,11 +202,11 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 
 	response, err := m.ExecuteAdsReadWriteRequest(ctx, uint32(driverModel.ReservedIndexGroups_ADSIGRP_MULTIPLE_READ), uint32(len(directAdsTags)), expectedResponseDataSize, requestItems, nil)
 	if err != nil {
-		result <- &internalModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error executing multi-item read request"),
-		}
+		result <- internalModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			nil,
+			errors.Wrap(err, "error executing multi-item read request"),
+		)
 		return
 	}
 
@@ -246,11 +247,11 @@ func (m *Connection) multiRead(ctx context.Context, readRequest apiModel.PlcRead
 	}
 
 	// Return the response to the caller.
-	result <- &internalModel.DefaultPlcReadRequestResult{
-		Request:  readRequest,
-		Response: internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
-		Err:      nil,
-	}
+	result <- internalModel.NewDefaultPlcReadRequestResult(
+		readRequest,
+		internalModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues),
+		nil,
+	)
 }
 
 func (m *Connection) parsePlcValue(dataType driverModel.AdsDataTypeTableEntry, arrayInfo []driverModel.AdsDataTypeArrayInfo, rb utils.ReadBufferByteBased) (values.PlcValue, error) {
diff --git a/plc4go/internal/ads/Subscriber.go b/plc4go/internal/ads/Subscriber.go
index 3a66f23847..df73d2be3d 100644
--- a/plc4go/internal/ads/Subscriber.go
+++ b/plc4go/internal/ads/Subscriber.go
@@ -61,14 +61,12 @@ func (m *Connection) Subscribe(ctx context.Context, subscriptionRequest apiModel
 			symbolicTag := tag.(dirverModel.SymbolicPlcTag)
 			directTagPtr, err := m.driverContext.getDirectTagForSymbolTag(symbolicTag)
 			if err != nil {
-				subResults[tagName] = &internalModel.DefaultPlcSubscriptionRequestResult{
-					Request: nil, Err: errors.Wrap(err, "error resolving symbolic tag")}
+				subResults[tagName] = internalModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.Wrap(err, "error resolving symbolic tag"))
 				continue
 			}
 			directTag = *directTagPtr
 		default:
-			subResults[tagName] = &internalModel.DefaultPlcSubscriptionRequestResult{
-				Request: nil, Err: errors.New("invalid tag type")}
+			subResults[tagName] = internalModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.New("invalid tag type"))
 			continue
 		}
 
@@ -142,23 +140,26 @@ func (m *Connection) subscribe(ctx context.Context, subscriptionRequest apiModel
 
 		response, err := m.ExecuteAdsAddDeviceNotificationRequest(ctx, directTag.IndexGroup, directTag.IndexOffset, directTag.DataType.GetSize(), model.AdsTransMode_ON_CHANGE, 0, 0)
 		if err != nil {
-			respChan <- &internalModel.DefaultPlcSubscriptionRequestResult{
-				Request:  subscriptionRequest,
-				Response: nil,
-				Err:      err,
-			}
+			responseChan <- internalModel.NewDefaultPlcSubscriptionRequestResult(
+				subscriptionRequest,
+				nil,
+				err,
+			)
 		}
 		// Create a new subscription handle.
 		subscriptionHandle := dirverModel.NewAdsSubscriptionHandle(m, tagName, directTag)
-		respChan <- &internalModel.DefaultPlcSubscriptionRequestResult{
-			Request: subscriptionRequest,
-			Response: internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest,
+		responseChan <- internalModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			internalModel.NewDefaultPlcSubscriptionResponse(
+				subscriptionRequest,
 				map[string]apiModel.PlcResponseCode{tagName: apiModel.PlcResponseCode_OK},
-				map[string]apiModel.PlcSubscriptionHandle{tagName: subscriptionHandle}),
-		}
+				map[string]apiModel.PlcSubscriptionHandle{tagName: subscriptionHandle},
+			),
+			nil,
+		)
 		// Store it together with the returned ADS handle.
 		m.subscriptions[response.GetNotificationHandle()] = subscriptionHandle
-	}(responseChan)
+	}()
 	return responseChan
 }
 
@@ -199,11 +200,11 @@ func (m *Connection) processSubscriptionResponses(_ context.Context, subscriptio
 			}
 		}
 	}
-	return &internalModel.DefaultPlcSubscriptionRequestResult{
-		Request:  subscriptionRequest,
-		Response: internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionHandles),
-		Err:      err,
-	}
+	return internalModel.NewDefaultPlcSubscriptionRequestResult(
+		subscriptionRequest,
+		internalModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionHandles),
+		err,
+	)
 }
 
 func (m *Connection) handleIncomingDeviceNotificationRequest(deviceNotificationRequest model.AdsDeviceNotificationRequest) {
diff --git a/plc4go/internal/ads/Writer.go b/plc4go/internal/ads/Writer.go
index d2330be112..4750aa4f23 100644
--- a/plc4go/internal/ads/Writer.go
+++ b/plc4go/internal/ads/Writer.go
@@ -70,33 +70,25 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 	if model.NeedsResolving(tag) {
 		adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
 		// Replace the symbolic tag with a direct one
 		tag, err = m.resolveSymbolicTag(ctx, adsField)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
 	}
 	directAdsTag, ok := tag.(*model.DirectPlcTag)
 	if !ok {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.New("invalid tag item type"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 		log.Debug().Msgf("Invalid tag item type %T", tag)
 		return
 	}
@@ -106,11 +98,7 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 	io := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.LittleEndian))
 	err := m.serializePlcValue(directAdsTag.DataType, directAdsTag.GetArrayInfo(), value, io)
 	if err != nil {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error serializing plc value"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error serializing plc value"))
 		return
 	}
 	data := io.GetBytes()
@@ -139,11 +127,7 @@ func (m *Connection) singleWrite(ctx context.Context, writeRequest apiModel.PlcW
 			responseCodes[tagName] = apiModel.PlcResponseCode_OK
 		}
 		// Return the response to the caller.
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-			Err:      nil,
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 	}()
 }
 
@@ -159,33 +143,21 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		if model.NeedsResolving(tag) {
 			adsField, err := model.CastToSymbolicPlcTagFromPlcTag(tag)
 			if err != nil {
-				result <- &internalModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 			// Replace the symbolic tag with a direct one
 			tag, err = m.resolveSymbolicTag(ctx, adsField)
 			if err != nil {
-				result <- &internalModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "invalid tag item type"),
-				}
+				result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "invalid tag item type"))
 				log.Debug().Msgf("Invalid tag item type %T", tag)
 				return
 			}
 		}
 		directAdsTag, ok := tag.(*model.DirectPlcTag)
 		if !ok {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -195,11 +167,7 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		// Serialize the plc value
 		err := m.serializePlcValue(directAdsTag.DataType, directAdsTag.GetArrayInfo(), writeRequest.GetValue(tagName), io)
 		if err != nil {
-			result <- &internalModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error serializing plc value"),
-			}
+			result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error serializing plc value"))
 			return
 		}
 
@@ -225,20 +193,12 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 		uint32(driverModel.ReservedIndexGroups_ADSIGRP_MULTIPLE_WRITE), uint32(len(directAdsTags)),
 		expectedResponseDataSize, requestItems, io.GetBytes())
 	if err != nil {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      errors.Wrap(err, "error executing multi-item write request"),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error executing multi-item write request"))
 		return
 	}
 
 	if response.GetResult() != driverModel.ReturnCode_OK {
-		result <- &internalModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: nil,
-			Err:      fmt.Errorf("got return result %s from remote", response.GetResult().String()),
-		}
+		result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, fmt.Errorf("got return result %s from remote", response.GetResult().String()))
 		return
 	}
 
@@ -259,11 +219,7 @@ func (m *Connection) multiWrite(ctx context.Context, writeRequest apiModel.PlcWr
 	}
 
 	// Return the response to the caller.
-	result <- &internalModel.DefaultPlcWriteRequestResult{
-		Request:  writeRequest,
-		Response: internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-		Err:      nil,
-	}
+	result <- internalModel.NewDefaultPlcWriteRequestResult(writeRequest, internalModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 }
 
 func (m *Connection) serializePlcValue(dataType driverModel.AdsDataTypeTableEntry, arrayInfo []apiModel.ArrayInfo, plcValue values.PlcValue, wb utils.WriteBufferByteBased) error {
diff --git a/plc4go/internal/bacnetip/Discoverer.go b/plc4go/internal/bacnetip/Discoverer.go
index a5f3deb9a1..70126d4c1b 100644
--- a/plc4go/internal/bacnetip/Discoverer.go
+++ b/plc4go/internal/bacnetip/Discoverer.go
@@ -157,7 +157,7 @@ func broadcastAndDiscover(ctx context.Context, communicationChannels []communica
 
 		go func(communicationChannelInstance communicationChannel) {
 			for {
-				blockingReadChan := make(chan bool, 0)
+				blockingReadChan := make(chan bool)
 				go func() {
 					buf := make([]byte, 4096)
 					n, addr, err := communicationChannelInstance.unicastConnection.ReadFrom(buf)
@@ -255,12 +255,14 @@ func handleIncomingBVLCs(ctx context.Context, callback func(event apiModel.PlcDi
 				if err != nil {
 					log.Debug().Err(err).Msg("Error parsing url")
 				}
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "bacnet-ip",
-					TransportCode: "udp",
-					TransportUrl:  *remoteUrl,
-					Name:          fmt.Sprintf("device %v:%v", iAm.GetDeviceIdentifier().GetObjectType(), iAm.GetDeviceIdentifier().GetInstanceNumber()),
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"bacnet-ip",
+					"udp",
+					*remoteUrl,
+					nil,
+					fmt.Sprintf("device %v:%v", iAm.GetDeviceIdentifier().GetObjectType(), iAm.GetDeviceIdentifier().GetInstanceNumber()),
+					nil,
+				)
 
 				// Pass the event back to the callback
 				callback(discoveryEvent)
@@ -270,12 +272,14 @@ func handleIncomingBVLCs(ctx context.Context, callback func(event apiModel.PlcDi
 				if err != nil {
 					log.Debug().Err(err).Msg("Error parsing url")
 				}
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "bacnet-ip",
-					TransportCode: "udp",
-					TransportUrl:  *remoteUrl,
-					Name:          fmt.Sprintf("device %v:%v with %v:%v and %v", iHave.GetDeviceIdentifier().GetObjectType(), iHave.GetDeviceIdentifier().GetInstanceNumber(), iHave.GetObjectIdentifier().GetObjectType(), iHave.GetObjectIdentifier().GetInstanceNumber(), iHave.GetObjectName().GetValue()),
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"bacnet-ip",
+					"udp",
+					*remoteUrl,
+					nil,
+					fmt.Sprintf("device %v:%v with %v:%v and %v", iHave.GetDeviceIdentifier().GetObjectType(), iHave.GetDeviceIdentifier().GetInstanceNumber(), iHave.GetObjectIdentifier().GetObjectType(), iHave.GetObjectIdentifier().GetInstanceNumber(), iHave.GetObjectName().GetValue()),
+					nil,
+				)
 
 				// Pass the event back to the callback
 				callback(discoveryEvent)
diff --git a/plc4go/internal/bacnetip/Reader.go b/plc4go/internal/bacnetip/Reader.go
index a1c1e7985a..3fdc4961ed 100644
--- a/plc4go/internal/bacnetip/Reader.go
+++ b/plc4go/internal/bacnetip/Reader.go
@@ -60,11 +60,7 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 	result := make(chan apiModel.PlcReadRequestResult, 1)
 	go func() {
 		if len(readRequest.GetTagNames()) == 0 {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("at least one field required"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(readRequest, nil, errors.New("at least one field required"))
 			return
 		}
 		// create the service request
@@ -167,29 +163,32 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 				readResponse, err := m.ToPlc4xReadResponse(apdu, readRequest)
 
 				if err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request: readRequest,
-						Err:     errors.Wrap(err, "Error decoding response"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "Error decoding response"),
+					)
 					return transaction.EndRequest()
 				}
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: readResponse,
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					readResponse,
+					nil,
+				)
 				return transaction.EndRequest()
 			}, func(err error) error {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "got timeout while waiting for response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "got timeout while waiting for response"),
+				)
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "error sending message"),
+				)
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/bacnetip/Subscriber.go b/plc4go/internal/bacnetip/Subscriber.go
index b60ea0b60a..adb088300c 100644
--- a/plc4go/internal/bacnetip/Subscriber.go
+++ b/plc4go/internal/bacnetip/Subscriber.go
@@ -21,9 +21,9 @@ package bacnetip
 
 import (
 	"context"
+	"github.com/pkg/errors"
 
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
-	plc4goModel "github.com/apache/plc4x/plc4go/spi/model"
 	spiModel "github.com/apache/plc4x/plc4go/spi/model"
 )
 
@@ -51,15 +51,15 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 		responseCodes := map[string]apiModel.PlcResponseCode{}
 		subscriptionValues := make(map[string]apiModel.PlcSubscriptionHandle)
 		for _, tagName := range internalPlcSubscriptionRequest.GetTagNames() {
+			if err := ctx.Err(); err != nil {
+				result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, err)
+				return
+			}
 			responseCodes[tagName] = apiModel.PlcResponseCode_OK
 			subscriptionValues[tagName] = spiModel.NewDefaultPlcSubscriptionHandle(m)
 		}
 
-		result <- &plc4goModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues), nil)
 	}()
 	return result
 }
diff --git a/plc4go/internal/cbus/Browser.go b/plc4go/internal/cbus/Browser.go
index d22e7a12cc..56c4ed7af8 100644
--- a/plc4go/internal/cbus/Browser.go
+++ b/plc4go/internal/cbus/Browser.go
@@ -107,16 +107,18 @@ func (m Browser) BrowseQuery(ctx context.Context, interceptor func(result apiMod
 					event.Msgf("unit %d: error reading tag %s. Code %s", unitAddress, attribute, code)
 					continue unitLoop
 				}
-				queryResult := &spiModel.DefaultPlcBrowseItem{
-					Tag:          NewCALIdentifyTag(unit, nil /*TODO: add bridge support*/, attribute, 1),
-					Name:         queryName,
-					Readable:     true,
-					Writable:     false,
-					Subscribable: false,
-					Options: map[string]values.PlcValue{
+				queryResult := spiModel.NewDefaultPlcBrowseItem(
+					NewCALIdentifyTag(unit, nil /*TODO: add bridge support*/, attribute, 1),
+					queryName,
+					"",
+					true,
+					false,
+					false,
+					nil,
+					map[string]values.PlcValue{
 						"CurrentValue": response.GetValue(readTagName),
 					},
-				}
+				)
 				if interceptor != nil {
 					interceptor(queryResult)
 				}
diff --git a/plc4go/internal/cbus/Discoverer.go b/plc4go/internal/cbus/Discoverer.go
index 00ba336fa5..9313c4592f 100644
--- a/plc4go/internal/cbus/Discoverer.go
+++ b/plc4go/internal/cbus/Discoverer.go
@@ -282,13 +282,14 @@ func (d *Discoverer) createDeviceScanDispatcher(tcpTransportInstance *tcp.Transp
 				}
 				// TODO: manufacturer + type would be good but this means two requests then
 				deviceName := identifyReplyCommand.GetManufacturerName()
-				discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-					ProtocolCode:  "c-bus",
-					TransportCode: "tcp",
-					TransportUrl:  remoteUrl,
-					Options:       nil,
-					Name:          deviceName,
-				}
+				discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+					"c-bus",
+					"tcp",
+					remoteUrl,
+					nil,
+					deviceName,
+					nil,
+				)
 				// Pass the event back to the callback
 				callback(discoveryEvent)
 				continue
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index c6df55f7cf..645595bbdf 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -62,10 +62,7 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 	}()
 	numTags := len(readRequest.GetTagNames())
 	if numTags > 20 { // letters g-z
-		result <- &spiModel.DefaultPlcReadRequestResult{
-			Request: readRequest,
-			Err:     errors.New("Only 20 tags can be handled at once"),
-		}
+		result <- spiModel.NewDefaultPlcReadRequestResult(readRequest, nil, errors.New("Only 20 tags can be handled at once"))
 		return
 	}
 	messages := make(map[string]readWriteModel.CBusMessage)
@@ -74,10 +71,11 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 		message, supportsRead, _, _, err := TagToCBusMessage(tag, nil, m.alphaGenerator, m.messageCodec)
 		switch {
 		case err != nil:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
+			)
 			return
 		case !supportsRead: // Note this should not be reachable
 			panic("this should not be possible as we always should then get the error above")
@@ -100,19 +98,21 @@ func (m *Reader) readSync(ctx context.Context, readRequest apiModel.PlcReadReque
 	}
 	for tagName, messageToSend := range messages {
 		if err := ctx.Err(); err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     err,
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				err,
+			)
 			return
 		}
 		m.createMessageTransactionAndWait(ctx, messageToSend, addResponseCode, tagName, addPlcValue)
 	}
 	readResponse := spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
-	result <- &spiModel.DefaultPlcReadRequestResult{
-		Request:  readRequest,
-		Response: readResponse,
-	}
+	result <- spiModel.NewDefaultPlcReadRequestResult(
+		readRequest,
+		readResponse,
+		nil,
+	)
 }
 
 func (m *Reader) createMessageTransactionAndWait(ctx context.Context, messageToSend readWriteModel.CBusMessage, addResponseCode func(name string, responseCode apiModel.PlcResponseCode), tagName string, addPlcValue func(name string, plcValue apiValues.PlcValue)) {
diff --git a/plc4go/internal/cbus/Subscriber.go b/plc4go/internal/cbus/Subscriber.go
index f1c72fa747..c9857a20d1 100644
--- a/plc4go/internal/cbus/Subscriber.go
+++ b/plc4go/internal/cbus/Subscriber.go
@@ -67,11 +67,11 @@ func (m *Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.P
 			subscriptionValues[tagName] = NewSubscriptionHandle(m, tagName, internalPlcSubscriptionRequest.GetTag(tagName), internalPlcSubscriptionRequest.GetType(tagName), internalPlcSubscriptionRequest.GetInterval(tagName))
 		}
 
-		result <- &spiModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/internal/cbus/Writer.go b/plc4go/internal/cbus/Writer.go
index 1808d03cf7..2883c0787b 100644
--- a/plc4go/internal/cbus/Writer.go
+++ b/plc4go/internal/cbus/Writer.go
@@ -57,11 +57,11 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 		}()
 		numTags := len(writeRequest.GetTagNames())
 		if numTags > 20 { // letters g-z
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("Only 20 tags can be handled at once"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.New("Only 20 tags can be handled at once"),
+			)
 			return
 		}
 
@@ -71,19 +71,19 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 			plcValue := writeRequest.GetValue(tagName)
 			message, _, supportsWrite, _, err := TagToCBusMessage(tag, plcValue, m.alphaGenerator, m.messageCodec)
 			if !supportsWrite {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding cbus message for tag %s. Tag is not meant to be written.", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(
+					writeRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding cbus message for tag %s. Tag is not meant to be written.", tagName),
+				)
 				return
 			}
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(
+					writeRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding cbus message for tag %s", tagName),
+				)
 				return
 			}
 			messages[tagName] = message
@@ -97,10 +97,7 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 		}
 		for tagName, messageToSend := range messages {
 			if err := ctx.Err(); err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request: writeRequest,
-					Err:     err,
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, err)
 				return
 			}
 			tagNameCopy := tagName
@@ -146,10 +143,7 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
 			})
 		}
 		readResponse := spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes)
-		result <- &spiModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: readResponse,
-		}
+		result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, readResponse, nil)
 	}()
 	return result
 }
diff --git a/plc4go/internal/eip/Reader.go b/plc4go/internal/eip/Reader.go
index b6f5576310..67dee5b772 100644
--- a/plc4go/internal/eip/Reader.go
+++ b/plc4go/internal/eip/Reader.go
@@ -108,30 +108,33 @@ func (m *Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest)
 						log.Trace().Msg("convert response to PLC4X response")
 						readResponse, err := m.ToPlc4xReadResponse(unconnectedDataItem.GetService(), readRequest)
 						if err != nil {
-							result <- &spiModel.DefaultPlcReadRequestResult{
-								Request: readRequest,
-								Err:     errors.Wrap(err, "Error decoding response"),
-							}
+							result <- spiModel.NewDefaultPlcReadRequestResult(
+								readRequest,
+								nil,
+								errors.Wrap(err, "Error decoding response"),
+							)
 							return transaction.EndRequest()
 						}
-						result <- &spiModel.DefaultPlcReadRequestResult{
-							Request:  readRequest,
-							Response: readResponse,
-						}
+						result <- spiModel.NewDefaultPlcReadRequestResult(
+							readRequest,
+							readResponse,
+							nil,
+						)
 						return transaction.EndRequest()
 					},
 					func(err error) error {
-						result <- &spiModel.DefaultPlcReadRequestResult{
-							Request: readRequest,
-							Err:     errors.Wrap(err, "got timeout while waiting for response"),
-						}
+						result <- spiModel.NewDefaultPlcReadRequestResult(
+							readRequest,
+							nil,
+							errors.Wrap(err, "got timeout while waiting for response"),
+						)
 						return transaction.EndRequest()
 					}, time.Second*1); err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request:  readRequest,
-						Response: nil,
-						Err:      errors.Wrap(err, "error sending message"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "error sending message"),
+					)
 					_ = transaction.EndRequest()
 				}
 			})
diff --git a/plc4go/internal/eip/Writer.go b/plc4go/internal/eip/Writer.go
index 8636a8d1d4..6522cec5f3 100644
--- a/plc4go/internal/eip/Writer.go
+++ b/plc4go/internal/eip/Writer.go
@@ -86,20 +86,12 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 			requestPathSize := int8(dataLength / 2)
 			data, err := encodeValue(value, eipTag.GetType(), elements)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding value for eipTag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding value for eipTag %s", tagName))
 				return
 			}
 			ansi, err := toAnsi(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding eip ansi for eipTag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding eip ansi for eipTag %s", tagName))
 				return
 			}
 			items[i] = readWriteModel.NewCipWriteRequest(ansi, eipTag.GetType(), elements, data, uint16(requestPathSize))
@@ -174,11 +166,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 							}
 							return transaction.EndRequest()
 						}, time.Second*1); err != nil {
-							result <- &spiModel.DefaultPlcWriteRequestResult{
-								Request:  writeRequest,
-								Response: nil,
-								Err:      errors.Wrap(err, "error sending message"),
-							}
+							result <- spiModel.NewDefaultPlcWriteRequestResult( writeRequest, nil,      errors.Wrap(err, "error sending message"))
 							_ = transaction.EndRequest()
 						}
 					})
@@ -269,11 +257,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 							}
 							return transaction.EndRequest()
 						}, time.Second*1); err != nil {
-							result <- &spiModel.DefaultPlcWriteRequestResult{
-								Request:  writeRequest,
-								Response: nil,
-								Err:      errors.Wrap(err, "error sending message"),
-							}
+							result <- spiModel.NewDefaultPlcWriteRequestResult( writeRequest, nil,      errors.Wrap(err, "error sending message"))
 							_ = transaction.EndRequest()
 						}
 					})
diff --git a/plc4go/internal/knxnetip/Browser.go b/plc4go/internal/knxnetip/Browser.go
index 19d5e84561..88905c36d0 100644
--- a/plc4go/internal/knxnetip/Browser.go
+++ b/plc4go/internal/knxnetip/Browser.go
@@ -103,13 +103,20 @@ func (m Browser) executeDeviceQuery(ctx context.Context, query DeviceQuery, inte
 			// If the request returned a connection, process it,
 			// otherwise just ignore it.
 			if deviceConnection.connection != nil {
-				queryResult := &model.DefaultPlcBrowseItem{
-					Tag: NewDeviceQuery(
+				queryResult := model.NewDefaultPlcBrowseItem(
+					NewDeviceQuery(
 						strconv.Itoa(int(knxAddress.GetMainGroup())),
 						strconv.Itoa(int(knxAddress.GetMiddleGroup())),
 						strconv.Itoa(int(knxAddress.GetSubGroup())),
 					),
-				}
+					"",
+					"",
+					false,
+					false,
+					false,
+					nil,
+					nil,
+				)
 
 				// Pass it to the callback
 				add := true
@@ -398,13 +405,16 @@ func (m Browser) executeCommunicationObjectQuery(ctx context.Context, query Comm
 					&tagType)
 			}
 
-			results = append(results, &model.DefaultPlcBrowseItem{
-				Tag:          tag,
-				Name:         fmt.Sprintf("#%d", comObjectNumber),
-				Readable:     readable,
-				Writable:     writable,
-				Subscribable: subscribable,
-			})
+			results = append(results, model.NewDefaultPlcBrowseItem(
+				tag,
+				fmt.Sprintf("#%d", comObjectNumber),
+				"",
+				readable,
+				writable,
+				subscribable,
+				nil,
+				nil,
+			))
 		}
 	} else if (m.connection.DeviceConnections[knxAddress].deviceDescriptor & 0xFFF0) == uint16(0x0700) /* System7 */ {
 		// For System 7 Devices we unfortunately can't access the information of where the memory address for the
@@ -477,13 +487,16 @@ func (m Browser) executeCommunicationObjectQuery(ctx context.Context, query Comm
 			for _, groupAddress := range groupAddresses {
 				tag := m.getTagForGroupAddress(groupAddress, tagType)
 
-				results = append(results, &model.DefaultPlcBrowseItem{
-					Tag:          tag,
-					Name:         fmt.Sprintf("#%d", comObjectNumber),
-					Readable:     readable,
-					Writable:     writable,
-					Subscribable: subscribable,
-				})
+				results = append(results, model.NewDefaultPlcBrowseItem(
+					tag,
+					fmt.Sprintf("#%d", comObjectNumber),
+					"",
+					readable,
+					writable,
+					subscribable,
+					nil,
+					nil,
+				))
 			}
 		}
 	} else {
diff --git a/plc4go/internal/knxnetip/Discoverer.go b/plc4go/internal/knxnetip/Discoverer.go
index 9bf2841602..2007cdb262 100644
--- a/plc4go/internal/knxnetip/Discoverer.go
+++ b/plc4go/internal/knxnetip/Discoverer.go
@@ -215,13 +215,14 @@ func (d *Discoverer) createDeviceScanDispatcher(udpTransportInstance *udp.Transp
 							continue
 						}
 						deviceName := string(bytes.Trim(searchResponse.GetDibDeviceInfo().GetDeviceFriendlyName(), "\x00"))
-						discoveryEvent := &internalModel.DefaultPlcDiscoveryItem{
-							ProtocolCode:  "knxnet-ip",
-							TransportCode: "udp",
-							TransportUrl:  *remoteUrl,
-							Options:       nil,
-							Name:          deviceName,
-						}
+						discoveryEvent := internalModel.NewDefaultPlcDiscoveryItem(
+							"knxnet-ip",
+							"udp",
+							*remoteUrl,
+							nil,
+							deviceName,
+							nil,
+						)
 						// Pass the event back to the callback
 						callback(discoveryEvent)
 					}
diff --git a/plc4go/internal/knxnetip/Reader.go b/plc4go/internal/knxnetip/Reader.go
index e3f22f7b2d..2fe1a23097 100644
--- a/plc4go/internal/knxnetip/Reader.go
+++ b/plc4go/internal/knxnetip/Reader.go
@@ -163,11 +163,11 @@ func (m Reader) Read(ctx context.Context, readRequest apiModel.PlcReadRequest) <
 
 		// Assemble the results
 		result := spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
-		resultChan <- &spiModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: result,
-			Err:      nil,
-		}
+		resultChan <- spiModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			result,
+			nil,
+		)
 	}()
 	return resultChan
 }
diff --git a/plc4go/internal/knxnetip/Subscriber.go b/plc4go/internal/knxnetip/Subscriber.go
index 7355e7e544..ae9da83cf2 100644
--- a/plc4go/internal/knxnetip/Subscriber.go
+++ b/plc4go/internal/knxnetip/Subscriber.go
@@ -67,11 +67,11 @@ func (m *Subscriber) Subscribe(ctx context.Context, subscriptionRequest apiModel
 			subscriptionValues[tagName] = NewSubscriptionHandle(m, tagName, internalPlcSubscriptionRequest.GetTag(tagName), tagType, internalPlcSubscriptionRequest.GetInterval(tagName))
 		}
 
-		result <- &spiModel.DefaultPlcSubscriptionRequestResult{
-			Request:  subscriptionRequest,
-			Response: spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
-			Err:      nil,
-		}
+		result <- spiModel.NewDefaultPlcSubscriptionRequestResult(
+			subscriptionRequest,
+			spiModel.NewDefaultPlcSubscriptionResponse(subscriptionRequest, responseCodes, subscriptionValues),
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/internal/knxnetip/Writer.go b/plc4go/internal/knxnetip/Writer.go
index 2ee56238e2..7b62ba14d7 100644
--- a/plc4go/internal/knxnetip/Writer.go
+++ b/plc4go/internal/knxnetip/Writer.go
@@ -50,11 +50,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		tag := writeRequest.GetTag(tagName)
 		groupAddressTag, err := CastToGroupAddressTagFromPlcTag(tag)
 		if err != nil {
-			result <- &plc4goModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("invalid tag item type"),
-			}
+			result <- plc4goModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("invalid tag item type"))
 			return result
 		}
 
@@ -63,11 +59,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		tagType := groupAddressTag.GetTagType()
 		// TODO: why do we ignore the bytes here?
 		if _, err := readWriteModel.KnxDatapointSerialize(value, *tagType); err != nil {
-			result <- &plc4goModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("error serializing value: " + err.Error()),
-			}
+			result <- plc4goModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("error serializing value: "+err.Error()))
 			return result
 		}
 	}
diff --git a/plc4go/internal/modbus/Reader.go b/plc4go/internal/modbus/Reader.go
index cac63f0b7e..586b840150 100644
--- a/plc4go/internal/modbus/Reader.go
+++ b/plc4go/internal/modbus/Reader.go
@@ -68,11 +68,11 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 		tag := readRequest.GetTag(tagName)
 		modbusTagVar, err := CastToModbusTagFromPlcTag(tag)
 		if err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "invalid tag item type"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "invalid tag item type"),
+			)
 			log.Debug().Msgf("Invalid tag item type %T", tag)
 			return
 		}
@@ -89,18 +89,18 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 		case HoldingRegister:
 			pdu = readWriteModel.NewModbusPDUReadHoldingRegistersRequest(modbusTagVar.Address, numWords)
 		case ExtendedRegister:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.New("modbus currently doesn't support extended register requests"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.New("modbus currently doesn't support extended register requests"),
+			)
 			return
 		default:
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Errorf("unsupported tag type %x", modbusTagVar.TagType),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Errorf("unsupported tag type %x", modbusTagVar.TagType),
+			)
 			log.Debug().Msgf("Unsupported tag type %x", modbusTagVar.TagType)
 			return
 		}
@@ -132,30 +132,33 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 			readResponse, err := m.ToPlc4xReadResponse(responseAdu, readRequest)
 
 			if err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "Error decoding response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "Error decoding response"),
+				)
 				// TODO: should we return the error here?
 				return nil
 			}
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: readResponse,
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				readResponse,
+				nil,
+			)
 			return nil
 		}, func(err error) error {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request: readRequest,
-				Err:     errors.Wrap(err, "got timeout while waiting for response"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "got timeout while waiting for response"),
+			)
 			return nil
 		}, time.Second*1); err != nil {
-			result <- &spiModel.DefaultPlcReadRequestResult{
-				Request:  readRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error sending message"),
-			}
+			result <- spiModel.NewDefaultPlcReadRequestResult(
+				readRequest,
+				nil,
+				errors.Wrap(err, "error sending message"),
+			)
 		}
 	}()
 	return result
diff --git a/plc4go/internal/modbus/Writer.go b/plc4go/internal/modbus/Writer.go
index 73251d2187..a28e718dce 100644
--- a/plc4go/internal/modbus/Writer.go
+++ b/plc4go/internal/modbus/Writer.go
@@ -70,11 +70,11 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 		value := writeRequest.GetValue(tagName)
 		data, err := readWriteModel.DataItemSerialize(value, modbusTag.Datatype, modbusTag.Quantity)
 		if err != nil {
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.Wrap(err, "error serializing value"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(
+				writeRequest,
+				nil,
+				errors.Wrap(err, "error serializing value"),
+			)
 			return
 		}
 
@@ -94,18 +94,10 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 				numWords,
 				data)
 		case ExtendedRegister:
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("modbus currently doesn't support extended register requests"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("modbus currently doesn't support extended register requests"))
 			return
 		default:
-			result <- &spiModel.DefaultPlcWriteRequestResult{
-				Request:  writeRequest,
-				Response: nil,
-				Err:      errors.New("unsupported tag type"),
-			}
+			result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.New("unsupported tag type"))
 			return
 		}
 
diff --git a/plc4go/internal/s7/Reader.go b/plc4go/internal/s7/Reader.go
index 8b327f973e..95a50c48e1 100644
--- a/plc4go/internal/s7/Reader.go
+++ b/plc4go/internal/s7/Reader.go
@@ -63,11 +63,11 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 			tag := readRequest.GetTag(tagName)
 			address, err := encodeS7Address(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
+				)
 				return
 			}
 			requestItems[i] = readWriteModel.NewS7VarRequestParameterItemAddress(address)
@@ -129,29 +129,32 @@ func (m *Reader) Read(ctx context.Context, readRequest model.PlcReadRequest) <-c
 				readResponse, err := m.ToPlc4xReadResponse(payload, readRequest)
 
 				if err != nil {
-					result <- &spiModel.DefaultPlcReadRequestResult{
-						Request: readRequest,
-						Err:     errors.Wrap(err, "Error decoding response"),
-					}
+					result <- spiModel.NewDefaultPlcReadRequestResult(
+						readRequest,
+						nil,
+						errors.Wrap(err, "Error decoding response"),
+					)
 					return transaction.EndRequest()
 				}
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: readResponse,
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					readResponse,
+					nil,
+				)
 				return transaction.EndRequest()
 			}, func(err error) error {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request: readRequest,
-					Err:     errors.Wrap(err, "got timeout while waiting for response"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "got timeout while waiting for response"),
+				)
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcReadRequestResult{
-					Request:  readRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcReadRequestResult(
+					readRequest,
+					nil,
+					errors.Wrap(err, "error sending message"),
+				)
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/s7/Writer.go b/plc4go/internal/s7/Writer.go
index b9a1773c48..870d98f8e1 100644
--- a/plc4go/internal/s7/Writer.go
+++ b/plc4go/internal/s7/Writer.go
@@ -62,21 +62,13 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 			plcValue := writeRequest.GetValue(tagName)
 			s7Address, err := encodeS7Address(tag)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding s7 address for tag %s", tagName))
 				return
 			}
 			parameterItems[i] = readWriteModel.NewS7VarRequestParameterItemAddress(s7Address)
 			value, err := serializePlcValue(tag, plcValue)
 			if err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrapf(err, "Error encoding value for tag %s", tagName),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding value for tag %s", tagName))
 				return
 			}
 			payloadItems[i] = value
@@ -150,11 +142,7 @@ func (m Writer) Write(ctx context.Context, writeRequest model.PlcWriteRequest) <
 				}
 				return transaction.EndRequest()
 			}, time.Second*1); err != nil {
-				result <- &spiModel.DefaultPlcWriteRequestResult{
-					Request:  writeRequest,
-					Response: nil,
-					Err:      errors.Wrap(err, "error sending message"),
-				}
+				result <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrap(err, "error sending message"))
 				_ = transaction.EndRequest()
 			}
 		})
diff --git a/plc4go/internal/simulated/Reader.go b/plc4go/internal/simulated/Reader.go
index cdb77f7350..11510260a5 100644
--- a/plc4go/internal/simulated/Reader.go
+++ b/plc4go/internal/simulated/Reader.go
@@ -92,11 +92,11 @@ func (r *Reader) Read(_ context.Context, readRequest model.PlcReadRequest) <-cha
 			r.tracer.AddTransactionalTrace(txId, "read", "success")
 		}
 		// Emit the response
-		ch <- &spiModel.DefaultPlcReadRequestResult{
-			Request:  readRequest,
-			Response: spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, responseValues),
-			Err:      nil,
-		}
+		ch <- spiModel.NewDefaultPlcReadRequestResult(
+			readRequest,
+			spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, responseValues),
+			nil,
+		)
 	}()
 	return ch
 }
diff --git a/plc4go/internal/simulated/Subscriber.go b/plc4go/internal/simulated/Subscriber.go
index 4f23a30b69..7bda6bad18 100644
--- a/plc4go/internal/simulated/Subscriber.go
+++ b/plc4go/internal/simulated/Subscriber.go
@@ -23,6 +23,8 @@ import (
 	"context"
 	apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
 	"github.com/apache/plc4x/plc4go/spi"
+	spiModel "github.com/apache/plc4x/plc4go/spi/model"
+	"github.com/pkg/errors"
 )
 
 type Subscriber struct {
@@ -40,13 +42,19 @@ func NewSubscriber(device *Device, options map[string][]string, tracer *spi.Trac
 }
 
 func (r Subscriber) Subscribe(_ context.Context, subscriptionRequest apiModel.PlcSubscriptionRequest) <-chan apiModel.PlcSubscriptionRequestResult {
+	// TODO: handle context
+	result := make(chan apiModel.PlcSubscriptionRequestResult)
+	result <- spiModel.NewDefaultPlcSubscriptionRequestResult(subscriptionRequest, nil, errors.New("Not Implemented"))
 	// TODO: implement me
-	return make(chan apiModel.PlcSubscriptionRequestResult)
+	return result
 }
 
 func (r Subscriber) Unsubscribe(_ context.Context, unsubscriptionRequest apiModel.PlcUnsubscriptionRequest) <-chan apiModel.PlcUnsubscriptionRequestResult {
+	// TODO: handle context
+	result := make(chan apiModel.PlcUnsubscriptionRequestResult, 1)
+	result <- spiModel.NewDefaultPlcUnsubscriptionRequestResult(unsubscriptionRequest, nil, errors.New("Not Implemented"))
 	// TODO: implement me
-	return make(chan apiModel.PlcUnsubscriptionRequestResult)
+	return result
 }
 
 func (r Subscriber) Register(consumer apiModel.PlcSubscriptionEventConsumer, handles []apiModel.PlcSubscriptionHandle) apiModel.PlcConsumerRegistration {
diff --git a/plc4go/internal/simulated/Writer.go b/plc4go/internal/simulated/Writer.go
index 0c2cd25447..9204a7db73 100644
--- a/plc4go/internal/simulated/Writer.go
+++ b/plc4go/internal/simulated/Writer.go
@@ -84,11 +84,7 @@ func (w *Writer) Write(_ context.Context, writeRequest model.PlcWriteRequest) <-
 			w.tracer.AddTransactionalTrace(txId, "write", "success")
 		}
 		// Emit the response
-		ch <- &spiModel.DefaultPlcWriteRequestResult{
-			Request:  writeRequest,
-			Response: spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes),
-			Err:      nil,
-		}
+		ch <- spiModel.NewDefaultPlcWriteRequestResult(writeRequest, spiModel.NewDefaultPlcWriteResponse(writeRequest, responseCodes), nil)
 	}()
 	return ch
 }
diff --git a/plc4go/spi/default/DefaultBrowser.go b/plc4go/spi/default/DefaultBrowser.go
index 4688d0aaf1..fc3a7e3e07 100644
--- a/plc4go/spi/default/DefaultBrowser.go
+++ b/plc4go/spi/default/DefaultBrowser.go
@@ -80,11 +80,11 @@ func (m *defaultBrowser) BrowseWithInterceptor(ctx context.Context, browseReques
 			responseCodes[queryName], results[queryName] = m.BrowseQuery(ctx, interceptor, queryName, query)
 		}
 		browseResponse := model.NewDefaultPlcBrowseResponse(browseRequest, results, responseCodes)
-		result <- &model.DefaultPlcBrowseRequestResult{
-			Request:  browseRequest,
-			Response: browseResponse,
-			Err:      nil,
-		}
+		result <- model.NewDefaultPlcBrowseRequestResult(
+			browseRequest,
+			browseResponse,
+			nil,
+		)
 	}()
 	return result
 }
diff --git a/plc4go/spi/model/DefaultPlcReadRequest.go b/plc4go/spi/model/DefaultPlcReadRequest.go
index 23653e5acb..553627e374 100644
--- a/plc4go/spi/model/DefaultPlcReadRequest.go
+++ b/plc4go/spi/model/DefaultPlcReadRequest.go
@@ -148,7 +148,7 @@ func (d *DefaultPlcReadRequest) ExecuteWithContext(ctx context.Context) <-chan a
 		for _, subResultChannel := range subResultChannels {
 			select {
 			case <-ctx.Done():
-				resultChannel <- &DefaultPlcReadRequestResult{Request: d, Err: ctx.Err()}
+				resultChannel <- NewDefaultPlcReadRequestResult(d, nil, ctx.Err())
 				return
 			case subResult := <-subResultChannel:
 				subResults = append(subResults, subResult)