Is it necessary to make the tensorflow serving system a lib jar package? - tensorflow-serving

First,I have to approval that the structure of the serving is very good. But in some scenario for example 'picture object detection' ,when a picture comes ,the picture need to be processed by many models, if we loop send the image to the remote server ,and wait the returns, it would be get a large delay, and Image transfer is very resource intensive。
Because our company use java to provide external RPC services,so
I packaged the tensorflow serving into a '.so' lib ,
then I provide a java api ,Java calls the native method of the c lib package
so users can call serving locally as if they were calling serving remotely. and At the same time, saving the time of remote transmission。 below is my java structure:
java
and the code in java is very simple:
public class TensorflowServerPredictorImpl {
static {
try {
NativeLibLoader.initLoad();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private final long handle;//server c impl handle
public native long init(byte[] options);
private native byte[] predict(long handle,byte[] request);
public TensorflowServerPredictorImpl(ServerOptions.ServerConfig config){
handle = init(config.toByteArray());
}
public Predict.PredictResponse Predict(Predict.PredictRequest request)throws Exception{
byte[] requestByteArray = request.toByteArray();
byte[] responseByteArray = predict(this.handle,requestByteArray);
Predict.PredictResponse response = Predict.PredictResponse.parseFrom(responseByteArray);
return response;
}
}
and the use of lib is just like:
public class Test{
public static void main(String[] args)throws Exception{
URL url = Test.class.getResource("/");
String path = url.getPath()+"model_config_file.cfg";
ServerOptions.ServerConfig.Builder builder = ServerOptions.ServerConfig.newBuilder();
builder.setModelConfigFile(path);
ServerOptions.ServerConfig config = builder.build();
TensorflowServerPredictorImpl predictor = new TensorflowServerPredictorImpl(config);
Predict.PredictRequest request =buildRequest(1);
Predict.PredictResponse response = predictor.Predict(request);
}
the predictor Support for multithreading。
How do other people solve such problems? Does it make sense for me to do this?

I had a similar problem to solve and installed a tensorflow serving application in a docker container. The requests for classification (in my case time series) are sent to the serving via grpc (protobuf) which is a binary format. This worked well so far. Although making the protobuf interface work in java was quite a steep learning phase.
But now I have also to serve several models in different technologies (tensoflow, python sklearn, ...) and some models cannot be served by tensorflow serving. So I have to setup a broker application in python which receives the requests from the java application and sends them out to many models. A new nice feature of the broker is that it can now do a voting over the results of the different models and send back only the voting result to java.

Related

Task Module call from Ms Teams in Bot Framework

I am looking to open a task module (Pop up - iframe with audio/video) in my bot that is connected to Teams channel. I am having issues following the sample code provided on the GitHub page.
I have tried to follow the sample and incorporate to my code by did not succeed.
In my bot.cs file I am creating card action of invoke type:
card.Buttons.Add(new CardAction("invoke", TaskModuleUIConstants.YouTube.ButtonTitle, null,null,null,
new Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>()
{
Data = TaskModuleUIConstants.YouTube.Id
}));
In my BotController.cs that inherits from Controller
[HttpPost]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await _adapter.ProcessAsync(Request, Response, _bot);
}
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
if (activity.Type == ActivityTypes.Invoke)
{
return HandleInvokeMessages(activity);
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
private HttpResponseMessage HandleInvokeMessages (Activity activity)
{
var activityValue = activity.Value.ToString();
if (activity.Name == "task/fetch")
{
var action = Newtonsoft.Json.JsonConvert.DeserializeObject<Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>>(activityValue);
Teams.Samples.TaskModule.Web.Models.TaskInfo taskInfo = GetTaskInfo(action.Data);
Teams.Samples.TaskModule.Web.Models.TaskEnvelope taskEnvelope = new Teams.Samples.TaskModule.Web.Models.TaskEnvelope
{
Task = new Teams.Samples.TaskModule.Web.Models.Task()
{
Type = Teams.Samples.TaskModule.Web.Models.TaskType.Continue,
TaskInfo = taskInfo
}
};
return msg;
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
There is more code as per the GitHub sample but I won't paste it here. Can someone point me into the correct direction ?
I have got to the stage that it is displaying a pop up window but the content and title comes from manifest file instead of creating actual iframe also no video is rendering. My goal is to render video within my teams using iframe container.
The important part from the sample:
This sample is deployed on Microsoft Azure and you can try it yourself by uploading Task Module CSharp.zip to one of your teams and/or as a personal app. (Sideloading must be enabled for your tenant; see step 6 here.) The app is running on the free Azure tier, so it may take a while to load if you haven't used it recently and it goes back to sleep quickly if it's not being used, but once it's loaded it's pretty snappy.
So,
Your Teams Admin MUST enable sideloading
Your bot MUST be sideloaded into Teams
The easiest way to do this would be download the sample manifest, open it in App Studio, then edit your bot information in. You then need to make sure Domains and permissions > Valid Domains are set for your bot. Also ensure you change the Tabs URLs to your own.
You also need to make sure that in your Tasks, the URLs they call ALL use https and not http. If anywhere in the chain is using http (like if you're using ngrok and http://localhost), it won't work.

S3A client and local S3 mock

To create end-to-end local tests of data workflow I utilize "mock S3" container (e.g adobe/S3Mock). Seems to work just fine. However, some parts of the system rely on S3A client. As far as I see, its format does not allow to point to particular nameserver or endpoint.
Is it possible to make S3A work in local environment?
you talking about the ASF Hadoop S3A Connector? Nobody has tested against S3 mock AFAIK (never seen it before!), but it does work with non-AWS endpoints
set fs.s3a.endpoint to the URL of your S3 connection. There's some settings about switching from https to http (fs.s3a.connection.ssl.enabled = false) and moving from virtual hosts to directories (fs.s3a.path.style.access = true) which will also be needed.
further reading
Like I said: nobody has done this. We developers just go against the main AWS endpoints with its problems (latency, inconsistency, error reporting, etc), precisely because its what you get in production. But for your local testing, it will simplify your life (and you can run it under jenkins without having to give it any secrets)
Answer by #stevel worked for me. Here is the code if someone wants to refer
class S3WriterTest {
private static S3Mock api;
private static AmazonS3 mockS3client;
#BeforeAll
public static void setUp() {
//start mock s3 service using findify
api = new S3Mock.Builder().withPort(8001).withInMemoryBackend().build();
api.start();
/* AWS S3 client setup.
* withPathStyleAccessEnabled(true) trick is required to overcome S3 default
* DNS-based bucket access scheme
* resulting in attempts to connect to addresses like "bucketname.localhost"
* which requires specific DNS setup.
*/
EndpointConfiguration endpoint = new EndpointConfiguration("http://localhost:8001", "us-west-2");
mockS3client = AmazonS3ClientBuilder
.standard()
.withEndpointConfiguration(endpoint)
.withPathStyleAccessEnabled(true)
.withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
.build();
mockS3client.createBucket("test-bucket");
}
#AfterAll
public static void tearDown() {
api.shutdown();
}
#Test
void unitTestForHadoopCodeWritingUsingS3A {
Configuration hadoopConfig = getTestConfiguration();
........
}
private static Configuration getTestConfiguration() {
Configuration config = new Configuration();
config.set("fs.s3a.endpoint", "http://127.0.0.1:8001");
config.set("fs.s3a.connection.ssl.enabled", "false");
config.set("fs.s3a.path.style.access", "true");
config.set("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider");
config.set("fs.s3a.access.key", "foo");
config.set("fs.s3a.secret.key", "bar");
return config;
}
}

JAX-RS Client API async request

I am trying to use the JAX-RS Client API to request a resource through HTTP GET, by using the following code: (I used jersey-client v2.12 and also resteasy-client v3.0.8.Final to test the implementation)
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.InvocationCallback;
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
client.target("http://example.com/").request().async().get(new InvocationCallback<String>() {
#Override
public void completed(String s) {
System.out.println("Async got: " + s);
}
#Override
public void failed(Throwable throwable) {
System.out.println("Async failure...");
}
});
}
}
As I expected the String is printed almost immediately. But the process keeps running about one minute, although there isn't any code that should be executed.
The JAX-RS spec just says that we should use the InvocationCallback and nothing else that matters to my issue. But even if I use a Future the same effect happens. I also tested, if this has something to do with a timeout, which was very unlikely and wrong. The debugger shows that there are some threads running namely DestroyJavaVM and jersey-client-async-executor-0 or pool-1-thread-1 in the case of resteasy.
Do you have any idea what is going wrong here?
It is allways helpful to consult the JavaDoc. Concerning my issue it says:
Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application. Client instances must be properly closed before being disposed to avoid leaking resources.
If I close the client properly everything is working as expected.
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
// request here
client.close();
}
}

Bad CRC32 in GZIP stream

I am using DevForce 2010 and Silverlight 4.
When saving entities that contain large amount of binary data, I get this error:
Unhandled Error in Silverlight Application The remote server returned an error: NotFound.
When debuging the application I see these errors:
Unhandled Error in Silverlight Application Insufficient memory to continue the execution of the program.
Bad CRC32 in GZIP stream.
I found this thread on Ideablades forum that discusses the problem: http://www.ideablade.com/forum/forum_posts.asp?TID=3361&PN=1&title=bad-crc32-in-gzip-stream
Is this a problem on the server or client?
Is this a problem that has been resolved in any new version of DevForce 2010?
My server has 4 GB memory. Would increasing the memory resolve the problem?
Or what would be the right solution?
Yes, the OnEndpointCreated overrides on both client and server are where you should add the customization. You can add the following to remove GZIP from the binding:
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint)
{
if (endpoint.Binding is CustomBinding)
{
var binding = endpoint.Binding as CustomBinding;
var elements = binding.CreateBindingElements();
// Swap out existing (GZIP) message encoding for binary
var encoding = elements.Find<MessageEncodingBindingElement>();
if (encoding != null)
{
elements.Remove(encoding);
encoding = new BinaryMessageEncodingBindingElement();
elements.Insert(0, encoding);
endpoint.Binding = new CustomBinding(elements);
}
}
}
DevForce will find your classes if they're in an assembly probed on the client/server.
This will turn off compression for everything from your DevForce client to the EntityServer, so may be a bit heavy-handed. You can turn on IIS compression to compress data sent to the client to help.
There haven't been any changes to GZIP processing since the 6.1.7 release of DevForce 2010. That thread still contains the best information of how to work around the problem: 1) modify the save logic or your entity definition to reduce the amount of data saved; 2) turn off use of GZIP; or 3) write a custom message encoder with another compression library.
Thank you Kim Johnson,
I have looked at the samples and I feel uncomfortable adding those config files and maybe breaking something that works fine today.
If I go the code-way, will I be ably to switch off GZIP and still retain the rest of the default settings for DevForce?
I guess the code below is what I should go for?
If I save these classes on the client and server, will DevForce automatically find these classes?
//Client
using System.ServiceModel.Channels;
using IdeaBlade.Core.Wcf.Extensions;
public class ProxyEvents : IdeaBlade.EntityModel.ServiceProxyEvents {
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint) {
base.OnEndpointCreated(endpoint);
// My client code turning GZIP off comes here?
}
public override void OnFactoryCreated(System.ServiceModel.ChannelFactory factory) {
base.OnFactoryCreated(factory);
}
}
//Server
using System.ServiceModel.Channels;
using IdeaBlade.Core.Wcf.Extensions;
public class ServiceEvents : IdeaBlade.EntityModel.Server.ServiceHostEvents {
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint) {
base.OnEndpointCreated(endpoint);
// My server code turning GZIP off comes here?
}
public override void OnServiceHostCreated(System.ServiceModel.ServiceHost host) {
base.OnServiceHostCreated(host);
}
}

Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC'

I'm using Sap Jco to connect to SAP database with the front end being Java(JSF), When I connect to SAP with:
try {
mConnection =JCO.createClient("400", // SAP client
"c3026902", // userid
"********", // password
"EN", // language
"iwdf5020", // host name
"00"); // system number
mConnection.connect();
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
Problem I'm facing is when run the application for the first time, data is displayed but when I re-run it says "Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC' "
Can any one help me in resolving the issue?????
This sounds like the API cannot load the native driver files.
The SAP Java Connector consists of a native runtime part, that does the actuall communication and a Java API that wraps this functionality with a java api.
The Java API is inside the sapjco.jar and the native drivers are e.g on windows inside librfc32.dll and sapjcorfc.dll.
Place these dll's into your system path (e.g. windows: C:\WiNDOWS\system32) and it should run.
Cheers
Sebastian
Are your DLLs located in the Windows system32 folder? If so, are you probably using the wrong architecture? (x64 DLL on 32 bit or vice versa)
Also, are the DLLs the same version as the java api? If you have SAP GUI installed there could be older DLLs around.
Defining SAP connection:
For the Version 3,0 of the sapjco library there exists plenty of useful information. To create a connection following the instructions in:
http://www.browseye.com/linkShare.html?url=http://help.sap.com/saphelp_nwpi711/helpdata/en/46/fb807cc7b46c30e10000000a1553f7/content.htm?bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1&bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1
There are a few thing that you should take into account:
Place the dll file in the same place that the jar.
The dll must be the right version for your operating system and architecture otherwise you will get a native library error.
Example of code to create a connection to the server.
public class StepByStepClient
{
static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL";
static
{
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "ls4065");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "85");
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "homofarber");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "laska");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
createDestinationDataFile(DESTINATION_NAME1, connectProperties);
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
createDestinationDataFile(DESTINATION_NAME2, connectProperties);
}
static void createDestinationDataFile(String destinationName, Properties connectProperties)
{
File destCfg = new File(destinationName+".jcoDestination");
try
{
FileOutputStream fos = new FileOutputStream(destCfg, false);
connectProperties.store(fos, "for tests only !");
fos.close();
}
catch (Exception e)
{
throw new RuntimeException("Unable to create the destination files", e);
}
}
public static void step1Connect() throws JCoException
{
JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
System.out.println("Attributes:");
System.out.println(destination.getAttributes());
System.out.println();
}
}
In SAPJco 3.0 connections are build from the info contained in a “Destination”.
The documentation example use a properties file to save the “Destination”. However it is a non-secure way to keep connection info. As is indicated on the documentation in the hightlighted paragraph you can see on next link.
http://help.sap.com/saphelp_nwpi711/helpdata/en/48/5fb9f9b523501ee10000000a421937/content.htm?bwsCriterion=%22In%20practice%20you%20should%20avoid%20this%20for%20security%20reasons.%22&bwsMatch=1
You can keep connection info on a database or any other storage system if you create a custom “DestinationDataProvider” In the Examples provided with the SAPJco library there is an example of how to create a custom DestinationDataProvider.