<commit_before>package com.microsoft.applicationinsights.library;

import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Looper;

import com.microsoft.applicationinsights.library.config.ISenderConfig;
import com.microsoft.applicationinsights.logging.InternalLogging;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;

/**
 * This singleton class sends data to the endpoint.
 */
class Sender {

    private static final String TAG = "Sender";
    /**
     * Synchronization LOCK for setting static config.
     */
    private static final Object LOCK = new Object();
    /**
     * Volatile boolean for double checked synchronize block.
     */
    private static volatile boolean isSenderLoaded = false;
    /**
     * The shared Sender instance.
     */
    private static Sender instance;
    /**
     * The configuration for this sender.
     */
    protected final ISenderConfig config;
    /**
     * Persistence object used to reserve, free, or delete files.
     */
    protected Persistence persistence;

    /**
     * Thread safe counter to keep track of num of operations
     */
    private AtomicInteger operationsCount;

    /**
     * Restrict access to the default constructor
     *
     * @param config the telemetryconfig object used to configure the telemetry module
     */
    protected Sender(ISenderConfig config) {
        this.config = config;
        this.operationsCount = new AtomicInteger(0);
        this.persistence = Persistence.getInstance();
    }

    /**
     * Initialize the INSTANCE of sender.
     */
    protected static void initialize(ISenderConfig config) {
        // note: isSenderLoaded must be volatile for the double-checked LOCK to work
        if (!Sender.isSenderLoaded) {
            synchronized (Sender.LOCK) {
                if (!Sender.isSenderLoaded) {
                    Sender.isSenderLoaded = true;
                    Sender.instance = new Sender(config);
                }
            }
        }
    }

    /**
     * @return the INSTANCE of the sender calls initialize before that.
     */
    protected static Sender getInstance() {
        if (Sender.instance == null) {
            InternalLogging.error(TAG, "getInstance was called before initialization");
        }

        return Sender.instance;
    }
    
    protected void sendDataOnAppStart() {
        kickOffAsyncSendingTask().execute();
    }

    private AsyncTask<Void, Void, Void> kickOffAsyncSendingTask() {
        return new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                sendNextFile();
                return null;
            }
        };
    }

    protected void sendNextFile() {
        //as sendNextFile() NOT guarranteed to be executed from a background thread, we need to
        //create an async task if necessary
        if (Looper.myLooper() == Looper.getMainLooper()) {
            InternalLogging.info(TAG, "Kick of new async task", "");
            kickOffAsyncSendingTask().execute();
        } else {
            if (runningRequestCount() < 10) {
                // Send the persisted data
                if (this.persistence != null) {
                    File fileToSend = this.persistence.nextAvailableFile();
                    if (fileToSend != null) {
                        send(fileToSend);
                    }
                }
            } else {
                InternalLogging.info(TAG, "We have already 10 pending reguests", "");
            }
        }
    }


    protected void send(File fileToSend) {
        String persistedData = this.persistence.load(fileToSend);
        if (!persistedData.isEmpty()) {
            InternalLogging.info(TAG, "sending persisted data", persistedData);
            try {
                InternalLogging.info(TAG, "sending persisted data", persistedData);
                this.operationsCount.getAndIncrement();
                this.sendRequestWithPayload(persistedData, fileToSend);
            } catch (IOException e) {
                InternalLogging.warn(TAG, "Couldn't send request with IOException: " + e.toString());
                this.operationsCount.getAndDecrement();
            }
        } else {
            this.persistence.deleteFile(fileToSend);
            sendNextFile();
        }
    }

    protected int runningRequestCount() {
        return this.operationsCount.get();
    }

    protected void sendRequestWithPayload(String payload, File fileToSend) throws IOException {
        Writer writer = null;
        URL url = new URL(config.getEndpointUrl());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setReadTimeout(config.getSenderReadTimeout());
        connection.setConnectTimeout(config.getSenderConnectTimeout());
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);

        try {
            InternalLogging.info(TAG, "writing payload", payload);
            writer = getWriter(connection);
            writer.write(payload);
            writer.flush();

            // Starts the query
            connection.connect();

            // read the response code while we're ready to catch the IO exception
            int responseCode = connection.getResponseCode();

            // process the response
            onResponse(connection, responseCode, payload, fileToSend);
        } catch (IOException e) {
            InternalLogging.warn(TAG, "Couldn't send data with IOException: " + e.toString());
            if (this.persistence != null) {
                this.persistence.makeAvailable(fileToSend); //send again later
            }
        } finally {<commit_msg>Add log statement in case we have an IOException on sending (==offline)<commit_after>package com.microsoft.applicationinsights.library;

import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Looper;

import com.microsoft.applicationinsights.library.config.ISenderConfig;
import com.microsoft.applicationinsights.logging.InternalLogging;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;

/**
 * This singleton class sends data to the endpoint.
 */
class Sender {

    private static final String TAG = "Sender";
    /**
     * Synchronization LOCK for setting static config.
     */
    private static final Object LOCK = new Object();
    /**
     * Volatile boolean for double checked synchronize block.
     */
    private static volatile boolean isSenderLoaded = false;
    /**
     * The shared Sender instance.
     */
    private static Sender instance;
    /**
     * The configuration for this sender.
     */
    protected final ISenderConfig config;
    /**
     * Persistence object used to reserve, free, or delete files.
     */
    protected Persistence persistence;

    /**
     * Thread safe counter to keep track of num of operations
     */
    private AtomicInteger operationsCount;

    /**
     * Restrict access to the default constructor
     *
     * @param config the telemetryconfig object used to configure the telemetry module
     */
    protected Sender(ISenderConfig config) {
        this.config = config;
        this.operationsCount = new AtomicInteger(0);
        this.persistence = Persistence.getInstance();
    }

    /**
     * Initialize the INSTANCE of sender.
     */
    protected static void initialize(ISenderConfig config) {
        // note: isSenderLoaded must be volatile for the double-checked LOCK to work
        if (!Sender.isSenderLoaded) {
            synchronized (Sender.LOCK) {
                if (!Sender.isSenderLoaded) {
                    Sender.isSenderLoaded = true;
                    Sender.instance = new Sender(config);
                }
            }
        }
    }

    /**
     * @return the INSTANCE of the sender calls initialize before that.
     */
    protected static Sender getInstance() {
        if (Sender.instance == null) {
            InternalLogging.error(TAG, "getInstance was called before initialization");
        }

        return Sender.instance;
    }
    
    protected void sendDataOnAppStart() {
        kickOffAsyncSendingTask().execute();
    }

    private AsyncTask<Void, Void, Void> kickOffAsyncSendingTask() {
        return new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                sendNextFile();
                return null;
            }
        };
    }

    protected void sendNextFile() {
        //as sendNextFile() NOT guarranteed to be executed from a background thread, we need to
        //create an async task if necessary
        if (Looper.myLooper() == Looper.getMainLooper()) {
            InternalLogging.info(TAG, "Kick of new async task", "");
            kickOffAsyncSendingTask().execute();
        } else {
            if (runningRequestCount() < 10) {
                // Send the persisted data
                if (this.persistence != null) {
                    File fileToSend = this.persistence.nextAvailableFile();
                    if (fileToSend != null) {
                        send(fileToSend);
                    }
                }
            } else {
                InternalLogging.info(TAG, "We have already 10 pending reguests", "");
            }
        }
    }


    protected void send(File fileToSend) {
        String persistedData = this.persistence.load(fileToSend);
        if (!persistedData.isEmpty()) {
            InternalLogging.info(TAG, "sending persisted data", persistedData);
            try {
                InternalLogging.info(TAG, "sending persisted data", persistedData);
                this.operationsCount.getAndIncrement();
                this.sendRequestWithPayload(persistedData, fileToSend);
            } catch (IOException e) {
                InternalLogging.warn(TAG, "Couldn't send request with IOException: " + e.toString());
                this.operationsCount.getAndDecrement();
            }
        } else {
            this.persistence.deleteFile(fileToSend);
            sendNextFile();
        }
    }

    protected int runningRequestCount() {
        return this.operationsCount.get();
    }

    protected void sendRequestWithPayload(String payload, File fileToSend) throws IOException {
        Writer writer = null;
        URL url = new URL(config.getEndpointUrl());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setReadTimeout(config.getSenderReadTimeout());
        connection.setConnectTimeout(config.getSenderConnectTimeout());
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);

        try {
            InternalLogging.info(TAG, "writing payload", payload);
            writer = getWriter(connection);
            writer.write(payload);
            writer.flush();

            // Starts the query
            connection.connect();

            // read the response code while we're ready to catch the IO exception
            int responseCode = connection.getResponseCode();

            // process the response
            onResponse(connection, responseCode, payload, fileToSend);
        } catch (IOException e) {
            InternalLogging.warn(TAG, "Couldn't send data with IOException: " + e.toString());
            if (this.persistence != null) {
                InternalLogging.info(TAG, "Persisting because of IOException: ", "We're probably offline =)");
                this.persistence.makeAvailable(fileToSend); //send again later
            }
        } finally {
{'fraction_non_alphanumeric': 0.09325601715783621, 'fraction_numerical': 0.0007943442688061005, 'mean_word_length': 2.227377595488336, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2149161', 'n_tokens_mistral': 3192, 'n_tokens_neox': 3088, 'n_words': 837}