Package Level
PM.bal
public type PM object {
public isolated function methodA(json config) returns error|http:Response;
public isolated function methodB(json config) returns error|http:Response;
public isolated function methodC(json config) returns sql:Client|error;
};
DefaultImplPM.bal
public class DefaultImplPM {
*PM;
public isolated function methodC(json config) returns sql:Client|error {
return new mysql:Client("dbConfig.host", "dbConfig.username", "dbConfig.password", "dbConfig.database");
}
public isolated function methodA(json config) returns error|http:Response {
http:Response response = new;
response.setJsonPayload("Default methodA is not implemented yet");
return response;
}
public isolated function methodB( json config) returns error|http:Response {
http:Response response = new;
response.setJsonPayload("Default methodB is not implemented yet");
return response;
}
}
Service level
newImpl.bal
import package as pkg;
public class NewImplPM {
*pkg:PM;
public isolated function methodC(json config) returns sql:Client|error {
return new mysql:Client("dbConfig.host", "dbConfig.username", "dbConfig.password", "dbConfig.database");
}
public isolated function methodA(json config) returns error|http:Response {
http:Response response = new;
response.setJsonPayload("new methodA is not implemented yet");
return response;
}
public isolated function methodB(json config) returns error|http:Response {
http:Response response = new;
response.setJsonPayload("new methodB is not implemented yet");
return response;
}
}
in service.bal
import package as pkg;
service /fr on new http:Listener(9090) {
pkg:PM pmVariable;
public function init() {
self.pmVariable = new DefaultImplPM();
}
resource isolated function post methodD(string c) returns error|http:Response {
return self.pmVariable.methodA(c);
}
resource isolated function post methodE(string c) returns error|http:Response {
return self.pmVariable.methodB(c);
}
}
I have some abstract methods for a use case which may have multiple different types of implementation for those methods. I want to given an basic implementation in a ballerina package level. That will be my default algorithm. When some one wants to give some additional support with a new algorithm implementation in service level. He/She should be able to do it by including my interface and implement those methods.
With this implementation, I got concurrent calls will not be made to this method since the service is not an 'isolated' service
warning. How to resolve this.
As indicated by the warning, this is because the service object is not isolated
(nor does it meet the requirements for an isolated
object to be inferred as one). Concurrent calls will be made to a resource method only if both the object and the method are isolated
. If the object is not isolated
, there can still be unsafe access of mutable state.
See concurrency safety, specifically isolated objects.
This service is not inferred as isolated
since it has a non-private mutable field (which is also not accessed within locks, does not meet transfer in/out conditions for an isolated
object, etc.).
You can explicitly mark the service declaration to identify and fix what's causing it to be non-isolated.
isolated service /fr on new http:Listener(9090) {
...
}
Generally, you would either have to
PM
an isolated object and pmVariable
a final
field orpmVariable
a private field and use locks when accessing it and introduce related changes (to ensure that the object is an isolated root)